> ## Documentation Index
> Fetch the complete documentation index at: https://www.pickfu.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# PickFu REST API reference and conventions

> Reference for the PickFu REST API, including base URL, Bearer token authentication, JSON request and response formats, and error handling.

## Base URL

All API requests should be made to:

```
https://api.pickfu.com/v1
```

## Authentication

All endpoints require a Bearer token in the Authorization header — either an **API key** or an **OAuth access token**:

```bash theme={null}
Authorization: Bearer sk_your_api_key_here
```

Create an API key at [Settings > API Keys](https://app.pickfu.com/settings/api-keys), or use OAuth for interactive apps. See the [Authentication](/authentication) guide for details.

## Request Format

* All request bodies must be JSON
* Set the `Content-Type: application/json` header for POST/PUT/PATCH requests
* All responses are returned as JSON

## Response Format

Successful responses include the requested data:

```json theme={null}
{
  "id": "abc123-def456",
  "name": "My Survey",
  "status": "completed"
}
```

## Error Handling

Error responses include an `error` type and human-readable `message`:

```json theme={null}
{
  "error": "Not Found",
  "message": "Survey not found"
}
```

### HTTP Status Codes

| Status Code | Description                                             |
| ----------- | ------------------------------------------------------- |
| `200`       | Success                                                 |
| `201`       | Created - resource successfully created                 |
| `400`       | Bad Request - invalid request body or parameters        |
| `401`       | Unauthorized - missing or invalid access token          |
| `403`       | Forbidden - insufficient permissions                    |
| `404`       | Not Found - resource doesn't exist                      |
| `429`       | Too Many Requests - rate limit exceeded                 |
| `500`       | Internal Server Error - something went wrong on our end |

### Validation Errors

When request validation fails, the response includes details about what went wrong:

```json theme={null}
{
  "error": "Bad Request",
  "message": "Validation failed",
  "details": [
    "question is required",
    "options must have at least 2 items"
  ]
}
```

## Rate Limits

API requests are rate-limited to **100 requests per minute** per access token.

When you exceed the rate limit, you'll receive a `429 Too Many Requests` response:

```json theme={null}
{
  "error": "Too Many Requests",
  "message": "Rate limit exceeded. Please wait before making more requests."
}
```

<Tip>
  Implement exponential backoff in your application to handle rate limiting gracefully.
</Tip>

## Pagination

Endpoints that return lists support pagination using `page` and `limit` query parameters:

```bash theme={null}
GET /v1/surveys?page=1&limit=20
```

Paginated responses include metadata:

```json theme={null}
{
  "data": [...],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 150,
    "totalPages": 8
  }
}
```

## Available Endpoints

<CardGroup cols={2}>
  <Card title="Surveys" icon="clipboard-question">
    Create, retrieve, publish, and manage surveys.
  </Card>

  <Card title="Responses" icon="comments">
    Read responses, send follow-up questions, and rate or pin responses.
  </Card>

  <Card title="Tags" icon="tag">
    Organize surveys with tags.
  </Card>

  <Card title="Projects" icon="folder">
    Group related surveys into projects.
  </Card>

  <Card title="Traits" icon="users">
    Audience targeting and reporting demographics.
  </Card>

  <Card title="Media" icon="image">
    Generate images from prompts and upload media to the CDN.
  </Card>

  <Card title="Playbooks" icon="book">
    Step-by-step research guides.
  </Card>
</CardGroup>

Explore the endpoints in the sidebar to see detailed documentation for each operation.

## Building surveys programmatically

<Note>
  **Don't add a separate "explain your reasoning" question.** Every PickFu response already includes a required written explanation — respondents have to type *why* they picked, ranked, or rated something before they can submit. When you `POST /surveys`, just write your real question (e.g. "Which product image makes you more likely to click?") and the qualitative `explanation` field comes back on the response automatically. Adding a second question to capture reasoning duplicates data and, in multi-question surveys, costs an extra question slot.

  Screen-recording surveys are the one exception — the recording itself is the answer, and the spoken response is returned as `mediaTranscription` rather than `explanation`. For every other question type the `explanation` field is populated on each response.
</Note>

The built-in explanation lives on each response object returned by `GET /surveys/{id}/responses` as the `explanation` field. If you need to dig deeper on a specific respondent's answer after the survey completes, use `POST /surveys/{id}/responses/{responseId}/followup` to send them a follow-up question through their PickFu inbox.
