Get started with the REST API

Base URL, token authentication, agent_id, idempotency keys, cursors, and the error shape. Rules shared by every API page.

View as MarkdownLast updated

Base URL

text
https://api.atmark.ai

Only the public identity lookup uses https://id.atmark.ai. See Identity lookup.

Authentication

Send the agent token in a header with every request. Never put it in the query string or body.

http
Authorization: Bearer atk_agent_...
  • A missing, wrong, revoked, or expired token returns 401 unauthorized.
  • A token without the needed scope, or a request for another agent's data, returns 403 forbidden.
  • Organization API keys (atk_org_…) don't work here. See Organization API keys.

agent_id

Many requests take an agent_id (32 lowercase hex characters) in the body or query. It must match the token's agent. Copy the agent ID from the agent's overview or from Identity › Identifiers in the console.

Idempotency keys

Requests that send mail or create schedules need an Idempotency-Key header (1–255 characters). Without it you get 400 idempotency_key_required.

  • Keys are scoped per agent and have no set expiry. Sending, replying, and forwarding share one key space; creating schedules has its own.
  • Repeat the same request with the same key and no second email goes out. Instead you get the message's current state with replayed: true. See Replayed requests.
  • Use the same key for a different request and you get 409 idempotency_key_reused.
  • After a timeout, a network error, a 500, or a 503, wait a little and retry with the same key. If the mail already went out, it won't go out twice.
  • A key that got 403 policy_denied stays denied. After fixing the cause, or waiting retry_after_seconds, send with a new key.

Lists and cursors

Lists take limit and cursor and return next_cursor. A null next_cursor means you've reached the end. Keep the same filters when asking for the next page.

Error shape

json
{ "error": "invalid_request", "detail": "…" }

Only branch on error. detail is for people and its wording can change. A first 403 policy_denied response carries message_id and decision instead of detail. See Messages. See Error codes.

Times

All times are ISO 8601 UTC strings, for example 2026-09-27T09:00:00.000Z.

Endpoints

MethodPathDocs
POST/v1/messagesMessages
POST/v1/threads/{threadId}/replyMessages
POST/v1/messages/{messageId}/forwardMessages
GET/v1/messages/inboundReceived mail
GET/v1/messages/inbound/{messageId}Received mail
GET/v1/messages/inbound/{messageId}/attachments/{index}Received mail
GET/v1/threads/{threadId}Threads
GET/v1/approvals/{approvalId}Approvals
GET/v1/agents/{agentId}/policyPolicy
POST · GET/v1/messages/scheduledScheduled email
GET/v1/messages/scheduled/{scheduleId}Scheduled email
POST/v1/messages/scheduled/{scheduleId}/cancelScheduled email
GET/v1/messages/verification-codeVerification codes
GET/v1/auditAudit records
POST · GET · DELETE/v1/agents/{agentId}/webhook-endpoints…Webhooks
GET · POST/v1/agents/{agentId}/webhook-deliveries…Webhooks
GEThttps://id.atmark.ai/v1/identity/{address}Identity lookup

Feedback on this page? Write to support@atmark.ai.