Skip to main content
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. API

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 https://api.production.services.disco.co/v1/docs.
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.

Create an API Key

API keys are created and managed in the Admin Area.
  1. Go to Admin AreaSettingsAPI.
  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 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
  • Create and remove Member Groups and subgroups
  • Manage Member Group membership
  • Pull basic engagement data for Members
  • Add Program, curriculum module, and curriculum item completions for existing Members, including a backfill mode for historical records
  • Review assignment submissions as passed or failed, with an optional review comment
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 https://api.production.services.disco.co/v1/docs.
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.

Create and Remove Member Groups

Use the Group endpoints to manage Member Groups and subgroups without working in the Admin Area:
  • group.create creates a Member Group or subgroup.
  • group.remove permanently removes a custom Member Group or subgroup.
group.create accepts:
  • name — optional. Must be 25 characters or less.
  • product_id — optional. Creates the Group inside a Program. Omit it to create an Academy-level Group. Groups can only be created for course Programs.
  • parent_group_id — optional. Creates a subgroup under the given parent Group. The parent must be a custom or default Group. When the parent Group belongs to a Program, you must also pass the product_id of that same Program. When creating a Program Group, omit this field to place the Group under the Program’s default Group.
  • color — optional. Hex color for the Group, 3 or 6 digits. Use 4 or 8 digits to include an alpha channel, for example #FFF5D680. Defaults to #FFF5D6.
  • description — optional. Must be 280 characters or less.
  • visibility — optional. everyone or admin_only. Defaults to everyone. Cannot be set on subgroups.
The response returns the created group with its id, name, product_id, parent_group_id, is_default_group, and visibility. Requests that fail validation return HTTP 400 with the code invalid_input and per-field field_errors. A product_id or parent_group_id that does not exist in your Academy returns HTTP 404. group.remove accepts a single group_id. Removing a parent Group also permanently removes all of its subgroups and their memberships. Only custom Groups can be removed:
  • Removing a default or platform-maintained Group (such as Program member or role Groups) returns HTTP 400 with the code not_custom_group.
  • Removing a Group that is still used by Events, Channels, or other Academy features returns HTTP 400 with the code group_in_use.

Complete Programs and Curriculum Modules

Use the completion endpoints to mark a Program, curriculum module, or curriculum item as complete for an existing member:
  • product.complete completes a Program. Optionally set complete_all_children to true to complete every curriculum item and module first.
  • product.completeCurriculumModule completes a curriculum module identified by the module’s instance_id from product.getCurriculum. Optionally set complete_all_children to true to complete its items first. Completing the final required module also completes the Program.
  • product.completeCurriculumItem completes one curriculum item identified by the item’s instance_id from product.getCurriculum. Completing the final required item also completes the module.
Completing a module or item may automatically complete its parent when the parent’s completion requirements are met. All three endpoints support 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 without notifications, certificates, automations, webhooks, or Zapier events. Program backfills still update pathway progression. 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); module and item entries also require instance_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. Retrying an existing Program completion with complete_all_children: true still fills any missing child completions.

Review Assignment Submissions

The content.reviewAssignment endpoint marks an assignment submission as passed or failed. Use it when work is evaluated outside Disco — in a grading tool, a rubric app, or a human review queue — and the decision needs to flow back into the Program. The assignment must have Require Pass to Progress enabled before its submissions can be reviewed. Submissions on any other assignment are rejected with the code grading_not_enabled. Each request accepts:
  • assignment_submission_id — the submission being reviewed.
  • statuspass or fail.
  • reviewer_user_id — the Academy membership ID of the Admin the review comes from. They must be an active Member of your Academy with permission to mark assignments in the Program, so every review is attributed to a real person rather than to the API key.
  • review_comment_markdown — optional. Posts a comment to the submission’s comment thread as the reviewer. Standard Markdown constructs — headings, lists, emphasis, links, quotes, and code — are converted to Disco’s editor format. Posting a comment also requires the reviewer to be a member of the Program, so an Academy Admin who is not in the Program can review a submission but cannot comment on it. The maximum comment length is documented in the OpenAPI spec.
The response returns the updated submission with its new status, plus review_comment_id when a comment was posted. Reviews made through the API behave the same as reviews made in the app: the Member is notified of the outcome, and passing the submission records the completion that unblocks their progress. When several Members submitted the assignment together, passing it completes the assignment for all of them. Reviewing the same submission again replaces the previous review. Marking a previously passed submission as failed updates the status but does not revoke the completion that was already recorded, matching what happens in the app.

Delete an API Key

Deleting a key is immediate and cannot be undone.
  1. Go to Admin AreaSettingsAPI.
  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 https://api.production.services.disco.co/v1/docs. Request bodies are also capped in size. A request whose body exceeds the cap returns HTTP 413 with the code payload_too_large, before any field-level validation runs. The cap and any per-field length limits are documented in the same OpenAPI spec.

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:
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

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.
No. The API is an Enterprise-only feature. If you need API access, talk to your Disco contact about upgrading.
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.
Most endpoints use POST so they can support pagination. Community.get is the only GET endpoint. Treat POST as the default when reading data.
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.
The content.user_submitted_assignment webhook event carries it as assignment_submission.id, which makes subscribing to that event the usual way to drive reviews: receive the submission, evaluate it in your own system, then send the result back with content.reviewAssignment. The same ID also appears in the submission’s URL when you open it in the app.
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.
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.