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

# Listen Labs API

> Create, launch, and retrieve data from Listen Labs studies programmatically

The Listen Labs API lets you run studies entirely from code: define a study guide as JSON, create a draft, launch it to get a self-recruit link you can distribute to participants, and pull responses back out once interviews come in.

## Base URL

```
https://listenlabs.ai
```

## Authentication

All endpoints authenticate with an API key passed in the `x-api-key` header. The key is scoped to a single organization — studies are created in, and wallets are listed for, that organization.

```bash theme={null}
curl 'https://listenlabs.ai/api/public/v1/wallets' \
  -H 'x-api-key: <api_key>'
```

Admins and Supervisors can create API keys from the **Developer** section of their account page on Listen. See [Get API Access](/get-api-access) for details.

## Workflow

<Steps>
  <Step title="Create a draft study">
    `POST /api/public/v1/studies/create` with a title and a [study guide](/api-v2/study-guide). The guide is validated up front; if it passes, you get back a draft study's `id` and `linkId`. Nothing is visible to participants yet — you can still review or edit the draft in the dashboard.
  </Step>

  <Step title="Pick a wallet (optional)">
    `GET /api/public/v1/wallets` lists the wallets granted to your organization with their recruitment and project credit balances. `walletId` can only be omitted at launch when your organization has exactly one wallet (it's auto-selected). If you have access to more than one, omitting it returns a `400` (`wallet_required`) — you must pass one from this list.
  </Step>

  <Step title="Launch">
    `POST /api/public/v1/studies/{studyId}/launch` publishes the draft and opens its self-recruit link. The response includes `selfRecruitLink` — share it with participants (or plug it into your own recruitment flow). Project responses bill to the launch wallet.
  </Step>

  <Step title="Retrieve responses">
    Once interviews come in, pull them with [Get Responses](/api-v2/list-responses) (`GET /api/public/v1/responses/{linkId}`) and drill into a single transcript with [Get Single Response](/api-v2/get-response). The `linkId` comes back from create/launch, or from [List Studies](/api-v2/list-studies). The [Data Map](/data-map) shows how these entities join together.
  </Step>
</Steps>

<Card title="Quickstart" icon="bolt" href="/api-v2/quickstart">
  A complete create → launch example you can copy and run.
</Card>

## Endpoints

| Endpoint | Description |
| - | - |
| [`POST /api/public/v1/studies/create`](/api-v2/create-study) | Validate a study guide and create a draft study |
| [`POST /api/public/v1/studies/{studyId}/launch`](/api-v2/launch-study) | Publish a draft and return the self-recruit link |
| [`GET /api/public/v1/wallets`](/api-v2/list-wallets) | List the organization's wallets with balances |
| [`GET /api/public/v1/studies`](/api-v2/list-studies) | List studies with response counts, creators, and folder paths |
| [`GET /api/public/v1/studies/{studyId}/questions`](/api-v2/get-study-questions) | Get a study's questions and concepts |
| [`GET /api/public/v1/responses/{linkId}`](/api-v2/list-responses) | List all responses for a study |
| [`GET /api/public/v1/responses/{linkId}/{responseId}`](/api-v2/get-response) | Retrieve a single response |
| [`GET /api/public/v1/responses`](/api-v2/search-responses) | Search responses by an exact URL parameter value |
| [`DELETE /api/public/v1/responses`](/api-v2/delete-response) | Request asynchronous response deletion |
| [`GET /api/public/v1/response-deletions/{deletionId}`](/api-v2/get-response-deletion-status) | Check deletion status |

## Errors

Every error response from the `/api/public/v1/*` endpoints shares one JSON envelope:

* `error` — a human-readable message. Useful for logs, but it may change; **don't** branch on it.
* `code` — a stable, machine-readable identifier. **Branch on this.**
* `issues` — present only on `400` schema failures (`code: invalid_request_body`): an array of per-field violations, each with a `path` and `message`.

```json 400 Schema violation theme={null}
{
  "error": "Invalid request body",
  "code": "invalid_request_body",
  "issues": [
    {
      "code": "invalid_type",
      "expected": "string",
      "received": "undefined",
      "path": ["title"],
      "message": "Required"
    }
  ]
}
```

```json 400 Invalid study guide theme={null}
{
  "error": "Invalid study guide: conditional references unknown item externalId 'q2'",
  "code": "invalid_study_guide"
}
```

### Error codes

| Status | Code | Meaning |
| - | - | - |
| `400` | `invalid_json` | Request body isn't valid JSON. |
| `400` | `invalid_request_body` | Body failed schema validation. See `issues` for per-field details. |
| `400` | `invalid_study_guide` | The study guide broke a cross-field rule (create only). |
| `400` | `wallet_required` | The organization has multiple wallets and `walletId` was omitted (launch only). |
| `400` | `insufficient_credits` | The wallet can't fund the launch — insufficient balance or grant limit (launch only). |
| `400` | `bad_request` | A query or path parameter is invalid (response endpoints only). |
| `401` | `missing_api_key` | No `x-api-key` header. |
| `401` | `invalid_api_key` | The API key is invalid. |
| `403` | `forbidden` | The key's user isn't a member of the key's organization. |
| `403` | `launch_permission_denied` | The key's user lacks permission to launch this study. |
| `403` | `wallet_access_denied` | No access to the specified wallet. |
| `404` | `study_not_found` | Study not found in the key's organization. |
| `404` | `response_not_found` | Response not found in the study (get response only). |
| `404` | `not_found` | Response or deletion not found in the key's organization (deletion endpoints only). |
| `409` | `concurrent_modification` | The draft was modified concurrently; retry (create only). |
| `409` | `study_busy` | An update is in flight; retry after a moment (launch only). |
| `409` | `conflict` | The publish raced a concurrent edit; refresh and retry (launch only). |
| `500` | `internal_error` | Internal error. Details are logged server-side, not returned. |

<Note>
  Beyond field-level validation, the server enforces cross-field rules on the study guide (screening block placement, `minSelect`/`maxSelect` coupling, unique `externalId`s, reference resolution, `exclusiveOption` placement) and returns violations as `400` responses (`code: invalid_study_guide`). The full list is in the [Study Guide Reference](/api-v2/study-guide#validation-rules).
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.