# UX Metrics API v1

REST API for UX Metrics study data. Supports JSON and Markdown responses. Read endpoints are available on all plans. Write endpoints require an active subscription.

## Authentication

All endpoints (except this documentation) require a Bearer token in the `Authorization` header:

```
Authorization: Bearer uxm_v1_<64-char-hex>
```

API keys are workspace-scoped. Create and manage keys in your workspace settings.

## Base URL

```
https://app.uxmetrics.com/api/v1
```

## Response Format

**JSON** (default): All endpoints return JSON by default with this envelope:

```json
{
  "data": { ... },
  "pagination": { "has_more": true, "next_cursor": "..." }
}
```

**Markdown**: Send `Accept: text/markdown` header to receive structured markdown instead of JSON. Useful for AI agents and LLMs that process text natively.

## Read Endpoints

| Method | Path | Description |
|--------|------|-------------|
| GET | `/api/v1/workspace` | Current workspace details |
| GET | `/api/v1/folders` | List folders (`?archived=false`) |
| GET | `/api/v1/folders/:id` | Folder detail |
| GET | `/api/v1/studies` | List studies (`?type=`, `?status=`, `?folder_id=`) |
| GET | `/api/v1/studies/:id` | Study detail with type-specific data |
| GET | `/api/v1/studies/:id/metrics` | Metrics only (lightweight) |
| GET | `/api/v1/studies/:id/report.md` | Full study report as markdown |
| GET | `/api/v1/studies/:id/participants` | List participants (`?excluded=false`) |
| GET | `/api/v1/studies/:id/participants/:pid` | Participant detail |
| GET | `/api/v1/studies/:id/participants/:pid/results` | Individual results |
| GET | `/api/v1/docs.md` | This documentation (no auth required) |

## Write Endpoints (subscription required)

### Folders

| Method | Path | Description |
|--------|------|-------------|
| POST | `/api/v1/folders` | Create a folder |
| PATCH | `/api/v1/folders/:id` | Update a folder |
| DELETE | `/api/v1/folders/:id` | Delete an empty folder |

**Create/Update body:** `{ "folder": { "name": "Research", "color": "#3B82F6", "icon": "folder" } }`

### Studies

| Method | Path | Description |
|--------|------|-------------|
| POST | `/api/v1/studies?type=card_sort` | Create a study (type required) |
| PATCH | `/api/v1/studies/:id` | Update study settings |
| DELETE | `/api/v1/studies/:id` | Delete a draft study |
| POST | `/api/v1/studies/:id/publish` | Publish a draft study |
| POST | `/api/v1/studies/:id/end` | End a published study |
| POST | `/api/v1/studies/:id/duplicate` | Duplicate a study |

**Create body:** `{ "study": { "name": "My Study", "folder_id": "fld_123" } }`

### Study Content

| Method | Path | Description |
|--------|------|-------------|
| POST | `/api/v1/studies/:id/cards` | Add cards (card sort only) |
| PATCH | `/api/v1/studies/:id/cards/:card_id` | Update a card |
| DELETE | `/api/v1/studies/:id/cards/:card_id` | Remove a card |
| POST | `/api/v1/studies/:id/groups` | Add groups (card sort only) |
| PATCH | `/api/v1/studies/:id/groups/:group_id` | Update a group |
| DELETE | `/api/v1/studies/:id/groups/:group_id` | Remove a group |
| POST | `/api/v1/studies/:id/questions` | Add questions (survey only) |
| PATCH | `/api/v1/studies/:id/questions/:question_id` | Update a question |
| DELETE | `/api/v1/studies/:id/questions/:question_id` | Remove a question |

### Participants

| Method | Path | Description |
|--------|------|-------------|
| POST | `/api/v1/studies/:id/participants/:pid/exclude` | Exclude a participant |
| POST | `/api/v1/studies/:id/participants/:pid/include` | Re-include a participant |

## ID Format

All IDs are prefixed for clarity:
- Workspaces: `ws_<id>`
- Folders: `fld_<id>`
- Studies: `std_<id>`
- Participants: `prt_<id>`
- Results: `res_<id>`

## Pagination

List endpoints use cursor-based pagination:

- `?limit=25` — items per page (default 25, max 100)
- `?after=<cursor>` — cursor from previous response's `pagination.next_cursor`

Response includes:
```json
{
  "pagination": {
    "has_more": true,
    "next_cursor": "eyJpZCI6MTIzfQ=="
  }
}
```

## Rate Limiting

Every response includes rate limit headers:

| Header | Description |
|--------|-------------|
| `X-RateLimit-Limit` | Requests allowed per minute |
| `X-RateLimit-Remaining` | Requests remaining in window |
| `X-RateLimit-Reset` | Unix timestamp when window resets |

Free workspaces: 60 requests/minute. Subscribed workspaces: 300 requests/minute.

When rate limited, you'll receive a `429 Too Many Requests` response with a `Retry-After` header.

## Study Types

The API supports all 9 UX Metrics study types:

| Type | Description |
|------|-------------|
| `card_sort` | Card sorting studies (open, closed, hybrid) |
| `tree_test` | Tree testing / information architecture validation |
| `survey` | Questionnaire-based studies |
| `first_click_test` | Click accuracy testing on images/wireframes |
| `five_second_test` | Impression/recall testing |
| `preference_test` | Visual preference comparison |
| `prototype_test` | Interactive prototype task testing |
| `live_website_test` | Real website task testing |
| `interview` | Qualitative interviews (guided or live) |

## Error Responses

```json
{
  "error": {
    "code": "not_found",
    "message": "Resource not found",
    "status": 404
  }
}
```

| Status | Code | When |
|--------|------|------|
| 400 | `invalid_request` | Missing required parameters |
| 401 | `unauthorized` | Missing or invalid API key |
| 403 | `forbidden` | API not enabled for workspace |
| 403 | `subscription_required` | Write endpoint without active subscription |
| 404 | `not_found` | Resource doesn't exist or is out of scope |
| 422 | `validation_failed` | Invalid data (details in response) |
| 422 | `invalid_type` | Invalid study type |
| 422 | `not_draft` | Cannot delete non-draft study |
| 422 | `invalid_status_transition` | Invalid status change |
| 422 | `has_studies` | Cannot delete folder with studies |
| 422 | `wrong_study_type` | Content endpoint used on wrong study type |
| 429 | `rate_limited` | Over rate limit |
| 500 | `internal_error` | Server error |
