Skip to content

API reference

Adam API overviewBeta

Build on Adam with OAuth, personal API keys, and the versioned REST API.

The Adam API lets you create projects, run AI engineering tasks, manage automations, upload input files, and download the files Adam produces. The production base URL is:

https://api.adam.new/v1

Authentication

Workspace owners and admins can disable API/MCP access or block individual permissions under Admin > API & MCP. These restrictions also apply to existing keys and OAuth connections. The separate tools:execute permission grants broad execution authority for client-driven tool calls; it is not implied by task or file write access.

Every API endpoint accepts either a personal API key or an Adam ID OAuth 2.0 access token.

Personal API keys

Create a personal API key for the workspace you want to use. Adam shows the secret once, so store it in a password manager or secret store. Send it as a Bearer token on every request:

bash
curl https://api.adam.new/v1/projects \
  -H "Authorization: Bearer $ADAM_API_KEY"

Personal keys act as you and are restricted to the workspace and scopes chosen when the key is created. Removing you from the workspace, revoking the key, or deleting your account immediately invalidates it.

OAuth

Installed apps and other public clients can use Adam ID's authorization-code flow with PKCE (S256). The flow opens Adam in the user's browser to sign in, choose a workspace, and approve scopes; the client receives an access token without handling the user's password or a long-lived personal key.

Start discovery from the API's protected-resource metadata:

https://api.adam.new/.well-known/oauth-protected-resource/v1

The authorization server is https://api.adam.new/auth. Send the RFC 8707 resource indicator https://api.adam.new/v1 on the authorization request and every token request, including authorization-code exchanges and refresh-token grants. A token issued for another Adam resource, including the MCP server, cannot authenticate to the REST API. Request offline_access when the client needs a refresh token.

Send the resulting access token using the same Bearer header:

bash
curl https://api.adam.new/v1/projects \
  -H "Authorization: Bearer $ADAM_ACCESS_TOKEN"

You can inspect the user, workspace, scopes, and credential type associated with either credential:

bash
curl https://api.adam.new/v1/auth/context \
  -H "Authorization: Bearer $ADAM_API_KEY"

Billing and integrations

Credentials with billing:read can retrieve a deliberately reduced subscription and usage snapshot from GET /v1/billing/summary. The response includes the effective plan, subscription state, renewal information, remaining usage percentages, and top-up balance. It does not expose payment methods, Stripe identifiers, raw credit accounting, or internal catalog IDs.

Credentials with integrations:read can list the integrations available to the selected workspace with GET /v1/integrations, or inspect one by stable slug with GET /v1/integrations/{integrationSlug}. Connection state reflects workspace-wide connections and the authenticated user's own user-scoped connections. Provider credentials, account metadata, and internal connection identifiers are never returned.

Automations

Use automations:read to list and inspect scheduled or webhook-triggered automations. automations:write permits creation, editing, pausing, resuming, and permanent deletion. Automation writes still enforce the same ownership, workspace-role, subscription, trigger, and scheduling checks as the Adam app.

Recurring schedules require a cron expression; one-time schedules require an ISO runAt timestamp. Webhook automations require a connected integration and a provider trigger event. Responses use effort and omit internal model-tier and provider-routing identifiers.

Idempotent writes

Adam accepts an optional Idempotency-Key when you create a project or automation and requires it when you create a task, send a message, or answer a task interaction. Use a new UUID for each logical operation and reuse it when retrying that operation. Adam replays the original response when both the key and request body match, and returns a conflict if the same key is reused for different input. Results are retained for 24 hours; using the same key after that window can execute a new request. Multipart uploads and task cancellation do not use an idempotency key.

bash
curl https://api.adam.new/v1/projects \
  -X POST \
  -H "Authorization: Bearer $ADAM_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"name":"Gearbox redesign"}'

Versions and limits

The major API version is part of the route. Compatible additions ship within /v1; breaking changes will use a new major path such as /v2 alongside the old one. When an endpoint or version is scheduled for removal, its responses carry Deprecation and Sunset headers at least 90 days before the retirement date, and the change is announced in the changelog.

Every request consumes from both a global per-credential bucket and a bucket for its operation type. Responses include the selected policy in X-RateLimit-Policy and describe both buckets:

Allowances are higher for workspaces with a paid subscription. These values are loaded from Adam's current configuration; response headers remain authoritative for an individual request.

Loading current rate limits…

HeaderDescription
RateLimit-PolicyStandard advertisement of every applicable quota policy: capacity (q) and window seconds (w)
RateLimitStandard live state of the most-constrained policy: remaining requests (r) and seconds until full (t)
X-RateLimit-LimitCapacity of the selected operation policy
X-RateLimit-RemainingWhole requests currently available under that policy
X-RateLimit-ResetUnix timestamp when that policy bucket will be full again
X-RateLimit-Global-LimitCapacity shared by all operations using the credential
X-RateLimit-Global-RemainingWhole requests currently available globally
X-RateLimit-Global-ResetUnix timestamp when the global bucket will be full again

The buckets refill continuously, so remaining quota can increase before the reset timestamp. If either bucket cannot accept a request, Adam returns 429 with Retry-After set to the number of seconds until both buckets can accept another request. Retry-After is omitted from successful responses.

All errors use one JSON shape and include a request ID you can send to support:

json
{
  "error": {
    "type": "invalid_request",
    "message": "Idempotency-Key header is required",
    "requestId": "019cf..."
  }
}

Asynchronous tasks

Creating a task or sending a message starts work asynchronously. Poll the task until its status is completed, failed, or cancelled. If the status is awaiting_input, read pendingInteraction and answer it with the interaction endpoint; Adam then continues the same task.

Paginate collections

Projects, tasks, task files, project files, and task messages use opaque cursor pagination. Set limit, then pass a non-null nextCursor back as cursor on the next request. Do not decode cursors or reuse one with a different endpoint.

You can filter tasks by projectId or by one public status: queued, running, awaiting_input, completed, cancelled, or failed.

Delete projects, tasks, and project files

DELETE /v1/projects/{projectId} permanently deletes a project you own. Its tasks and files survive and become ungrouped. DELETE /v1/tasks/{taskId} permanently deletes an owned task and its message history. Both operations require the corresponding write scope and cannot be undone.

DELETE /v1/projects/{projectId}/files/{fileId} removes a durable shared file from that project and requires both projects:write and files:write. Task files and message attachments are immutable because they form part of the task history.

Upload and attach files

Task attachments use a two-step flow. First upload the bytes with POST /v1/uploads. The returned upload ID is valid for 24 hours and is bound to the user and workspace represented by the credential.

bash
curl https://api.adam.new/v1/uploads \
  -X POST \
  -H "Authorization: Bearer $ADAM_API_KEY" \
  -F "file=@drawing.step"
json
{
  "upload": {
    "id": "adam_upload_...",
    "name": "drawing.step",
    "mediaType": "model/step",
    "size": 148320,
    "expiresAt": "2026-08-27T12:00:00.000Z"
  }
}

Reference that ID when creating a task or sending a message:

bash
curl https://api.adam.new/v1/tasks/$TASK_ID/messages \
  -X POST \
  -H "Authorization: Bearer $ADAM_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "content": "Check this drawing for manufacturing problems.",
    "attachments": [{"uploadId": "adam_upload_..."}]
  }'

Uploading and attaching files requires files:write. Creating a task or sending its message also requires tasks:write. You can omit the text when the attachment itself provides enough context.

To add a durable shared file directly to a project, send the multipart file to POST /v1/projects/{projectId}/files instead.

Read messages

Use GET /v1/tasks/{taskId}/messages for a paginated conversation. Messages contain typed parts; there is no separate flattened text field.

bash
curl "https://api.adam.new/v1/tasks/$TASK_ID/messages?limit=50" \
  -H "Authorization: Bearer $ADAM_API_KEY"
json
{
  "messages": [
    {
      "id": "message-id",
      "role": "user",
      "createdAt": "2026-08-26T12:00:00.000Z",
      "parts": [
        {"type": "text", "text": "Check this drawing."},
        {
          "type": "file",
          "id": "file-id",
          "name": "drawing.step",
          "mediaType": "model/step",
          "downloadUrl": "https://api.adam.new/v1/files/file-id/content"
        }
      ]
    }
  ],
  "nextCursor": null
}

When nextCursor is not null, pass it as the next request's cursor query parameter. File download URLs are absolute. You can also retrieve one file's metadata with GET /v1/files/{fileId} before downloading its content.

The message-part types returned by an Adam deployment depend on its transparency policy. Text, reasoning, and tool activity are enabled by default. Administrators can also expose files, URL sources, document sources, reasoning files, structured Adam data, provider-specific content, and model step boundaries. Disabled parts are omitted; a message with no exposed parts is omitted as well.

Assistant tool activity remains in order. Every invocation has a tool_call part. A completed invocation is immediately followed by a tool_result with a success, error, or denied status.

json
[
  {
    "type": "tool_call",
    "toolCallId": "call-1",
    "name": "bash",
    "input": {"command": "python build.py"}
  },
  {
    "type": "tool_result",
    "toolCallId": "call-1",
    "name": "bash",
    "status": "success",
    "output": {"exitCode": 0, "stdout": "Created bracket.step"}
  }
]

Tool inputs and successful outputs are JSON values. Error results contain an error string instead of output; denied results contain neither.