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

# API

Disco's API is a REST API that lets external systems programmatically manage Members, memberships, Programs, Pathways, Member Groups, invites, and magic login links in your Academy.

<img src="https://mintcdn.com/disco-e32b1565/P1hzDW8XN9fJBf-q/images/API.png?fit=max&auto=format&n=P1hzDW8XN9fJBf-q&q=85&s=699f1bb12bc5f2e00aec55d7fc3b4de9" alt="API" width="2240" height="1120" data-path="images/API.png" />

## **Overview**

The API is the pull-based half of Disco's developer toolkit. Use it to sync Members from a CRM, provision access from a sign-up flow, automate Admin and Manager assignments, or pull basic engagement data without working inside the Admin Area by hand. The API is available on the Enterprise plan only, and only Academy Owners and Admins can create or manage keys. Full endpoint reference and request and response schemas are published as OpenAPI documentation at[ <u>https://api.production.services.disco.co/v1/docs</u>](https://api.production.services.disco.co/v1/docs).

<Warning>
  The Disco API and Webhooks use older terminology. In API requests and responses, `Community` refers to what Disco now calls an **Academy**, and `Product` refers to what Disco now calls a **Program**. Keep this in mind when mapping API fields to what you see in the product.
</Warning>

## **Create an API Key**

API keys are created and managed in the Admin Area.

1. Go to **Admin Area** → **Settings** → **API**.
2. Click **+ API Key**.
3. Enter a Name. Names must be unique within your Academy.
4. Optionally set an Expiration Date. Leave it blank if the key should not expire.
5. Click **Save**.

The key is generated and its edit view opens so you can copy the value. Treat the key like a password and store it securely. The full key value remains accessible from the API Keys table if you need to retrieve it later.

## **Authenticate API Requests**

All requests are made against the base URL:

[https://api.production.services.disco.co/v1](https://api.production.services.disco.co/v1)

Authenticate every request by passing the key in the X-Disco-API-Key header. Disco does not accept Authorization or Bearer tokens.

## **Use the API**

The API supports the Member and content operations most teams need to automate:

* Add or remove Members in your Academy or Programs
* Create magic login links for Members
* Add or remove Admins or Managers in your Academy or Programs
* Invite Members to your Academy or Programs
* List Programs and the Members in those Programs
* List Member Groups and the Members in those Groups
* Manage Member Group membership
* Pull basic engagement data for Members
* Add Program completions for existing Members, including a backfill mode for historical records

List endpoints for Programs, Pathways, Members, and Member Groups accept an optional `filter` object in the request body. Programs and Pathways can be filtered by `name` and `slug`, Member Groups by `name`, and Members by `fullName`. Each filter value must be at least one character and is matched as a case-insensitive substring against the field.

For request and response schemas, see the OpenAPI docs at[ <u>https://api.production.services.disco.co/v1/docs</u>](https://api.production.services.disco.co/v1/docs).

<Note>
  Endpoints that list the Members of a Program (for example, `product.listUsers`) return only Members whose Program membership is currently **enrolled**. Members who were previously added to the Program but have since been unenrolled are excluded from the response, even if their underlying Academy membership still exists.
</Note>

## **Add Program Completions**

The `product.complete` endpoint marks one or more existing Program memberships as complete. It supports two modes:

* `standard` — completions run through the normal Disco workflows, so Members receive notifications, certificates are issued, automations fire, and webhook and Zapier events are emitted.
* `backfill` — completions are persisted and pathway progression is updated, but no notifications, certificates, automations, webhooks, or Zapier events are triggered. Use this mode when importing historical completion data.

Send up to 20 completions per request. Each entry accepts a `user_id` (the Member's Academy membership ID) and a `product_id` (the Program ID).

Responses return one result per input, in request order:

* **Success**: `success: true`, plus `created` (`true` if the request created the completion, `false` if the Member was already complete) and `completed_at` (the original completion time — existing completions are not overwritten).
* **Failure**: `success: false`, plus a `failure_code` and `failure_reason`. `not_found` covers missing, inaccessible, or ineligible records. `internal_error` is returned for unexpected failures on that single record while the rest of the batch continues to process.

Repeat calls are idempotent: sending the same completion twice returns `created: false` the second time and does not duplicate the record.

## **Delete an API Key**

Deleting a key is immediate and cannot be undone.

1. Go to **Admin Area** → **Settings** → **API**.
2. Locate the key in the **API Keys** table.
3. Open the **Action** menu and click **Delete**.

Any system using the deleted key stops working right away. There is no soft-disable option, so if you only want to pause a key temporarily, plan to issue a new one when you need it again.

## **Rate Limits**

Rate limits are applied per endpoint and per Academy. A request that exceeds the limit returns HTTP 429 with the message Rate Limited. Per-endpoint limits and the maximum number of IDs accepted by bulk endpoints are documented in the OpenAPI spec at[ <u>https://api.production.services.disco.co/v1/docs</u>](https://api.production.services.disco.co/v1/docs).

## **Input Validation**

Fields that accept Disco entity IDs (for example `group_id`, `pathway_id`, `invite_id`, `webhook_endpoint_id`, the `ids` and `pathway_ids` arrays, the `group_membership_ids` and `webhook_request_ids` arrays, and `profile_fields[].id`) must be passed as positive integer strings. Values that are not numeric, or that are larger than a Postgres `bigint`, are rejected before the request reaches the handler.

A request that fails ID validation returns HTTP 400 with a structured error body:

```json theme={null}
{
  "error": true,
  "code": "invalid_input",
  "message": "Invalid Input",
  "field_errors": [
    { "field": "group_id", "message": "must be a valid ID" }
  ]
}
```

When the offending value is inside an array, the `field` is the dotted path to the entry — for example `ids.0` or `profile_fields.0`. Previously these requests could return HTTP 500; they now consistently return HTTP 400 so clients can surface the error to the caller.

## **FAQ**

<AccordionGroup>
  <Accordion title="Do I need to ask Disco to enable the API?">
    No. If your Academy is on the Enterprise plan, the **API** settings page is already available in the Admin Area. Non-Enterprise plans do not see the page.
  </Accordion>

  <Accordion title="Can I use the API on a non-Enterprise plan?">
    No. The API is an Enterprise-only feature. If you need API access, talk to your Disco contact about upgrading.
  </Accordion>

  <Accordion title="I keep getting an authentication error. What am I doing wrong?">
    The most common cause is sending the key in the wrong header. Disco expects X-Disco-API-Key. Clients that default to Authorization: Bearer \<token> are rejected. Double-check the header name and confirm you copied the full key value.
  </Accordion>

  <Accordion title="Why do list and read endpoints use POST instead of GET?">
    Most endpoints use POST so they can support pagination. Community.get is the only GET endpoint. Treat POST as the default when reading data.
  </Accordion>

  <Accordion title="Where do I find the Program ID I need for an API call?">
    Open the Program in the Admin Area and go to **Settings**. The ID is shown there, and you can also grab it from the Admin URL when editing the Program. Use this value in any request that accepts a product\_id field.
  </Accordion>

  <Accordion title="Can I pull user activity like logins through the API?">
    The engagement.list endpoint returns engagement metrics per Member per day, filterable by user IDs and date range up to 120 days. It is the closest thing to a general activity feed. Explicit login events are not exposed.
  </Accordion>

  <Accordion title="What happens if a key expires?">
    The key stops working on the expiration date. Any integration using it will start receiving authentication errors until you issue and install a new key.
  </Accordion>
</AccordionGroup>
