API Tokens and Automations
Create and manage Personal Access Tokens (PATs) for programmatic access to your handle's data and operations.
Need help deciding between PAT and JWT for a specific endpoint? Start with JWT vs PAT: When to Use Each.
Key concepts
| Concept | What it means |
|---|---|
| PAT (Personal Access Token) | A long-lived API credential scoped to a specific handle and set of permissions |
| Scope | A permission grant (e.g., links.read, analytics.*). Each PAT has one or more scopes that limit what it can do |
| Token format | patv1_<tokenId>.<secret> — the secret is shown once at creation and cannot be retrieved again |
| Route family | PATs work on documented public-handle automation routes under /v2/public/handles/{handle}/. They cannot access control-plane routes like /v2/handles/ |
Available scopes
| Scope | What it allows |
|---|---|
links.read | List and read links |
links.write | Create, update, and delete links |
analytics.* | Query analytics and export data |
webhooks.* | Create, list, delete, and test webhook subscriptions |
files.read | List and read files |
files.write | Upload and delete files |
site.deployments.read | List site deployments and fetch deployment preview URLs |
site.deployments.write | Create site deployments (inline HTML and multifile manifests) |
pages.read | List creator pages for a handle |
pages.write | Create, update, delete, and publish pages and page-backed campaign structures |
context_store.search | Search/list replicated Context Store records and inspect source status through MCP |
context_store.manage | Request Context Store source refreshes through MCP |
tracking.templates.* | Manage tracking templates |
chain.signal.write | Submit chain signals |
personalization.* | Read personalization rules (write requires JWT) |
Create a PAT
Dashboard
Open API Tokens
Go to
https://app.10x.in, navigate to your handle, and open Settings → API Tokens.Create token
Click Create Token and name it (e.g.,
ci-analytics-reader).Select scopes
Choose the scopes you need.
Copy the secret
Click Create. The secret is displayed once — copy and store it securely.
API
```bash Request curl -sS -X POST "https://ai.10x.in/v2/handles/{handle}/tokens" \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"name": "ci-analytics-reader", "scopes": ["analytics.*", "links.read"]}' ``` ```json Body { "name": "ci-analytics-reader", "scopes": ["analytics.*", "links.read"] } ``` Returns 201 with the full token including the secret. The secret is only included in this response — subsequent reads show the token ID and scopes but not the secret.
Using a PAT
Include the PAT in the Authorization header:
Authorization: Bearer patv1_<tokenId>.<secret>
Or, where supported, use the x-api-key header:
x-api-key: patv1_<tokenId>.<secret>
Examples
curl -sS "https://ai.10x.in/v2/public/handles/acme/links" \
-H "Authorization: Bearer patv1_abc123.secret456"
curl -sS "https://ai.10x.in/v2/public/handles/acme/analytics?funnel=true" \
-H "Authorization: Bearer patv1_abc123.secret456"
curl -sS "https://ai.10x.in/v2/public/handles/acme/analytics?groupBy=ai_referrer" \
-H "Authorization: Bearer patv1_abc123.secret456"
curl -sS -X PUT "https://ai.10x.in/v2/public/handles/acme/links/new-launch" \
-H "Authorization: Bearer patv1_abc123.secret456" \
-H "Content-Type: application/json" \
-d '{"destinationUrl":"https://example.com/launch","title":"New Launch"}'
Manage tokens
List all tokens
curl -sS "https://ai.10x.in/v2/handles/{handle}/tokens" \
-H "Authorization: Bearer <access-token>"
Returns all active tokens for the handle (without secrets).
Revoke a token
curl -sS -X DELETE "https://ai.10x.in/v2/handles/{handle}/tokens/{tokenId}" \
-H "Authorization: Bearer <access-token>"
Required auth
- OPERATOR-level
JWTor above to create, list, and revoke tokens. - The PAT itself authenticates requests on
/v2/public/handles/{handle}/*routes.
When PAT is not enough
Use JWT (not PAT) for control-plane actions such as:
- collaborator management
- billing and checkout-session management
- account-domain operations
- PAT lifecycle endpoints themselves (
/v2/handles/{handle}/tokens*)
If you send a PAT to a JWT-only endpoint, expect a role/scope-style auth failure (commonly 403 insufficient_scope).
PAT-accessible endpoints
| Endpoint family | Required scope |
|---|---|
/v2/public/handles/{handle}/links | links.read or links.write |
/v2/public/handles/{handle}/analytics | analytics.* |
/v2/public/handles/{handle}/analytics/export | analytics.* |
/v2/public/handles/{handle}/webhooks | webhooks.* |
/v2/public/handles/{handle}/files | files.read or files.write |
/v2/public/handles/{handle}/site-deployments | site.deployments.read or site.deployments.write |
/v2/public/handles/{handle}/site-deployments/{deploymentId}/preview | site.deployments.read |
/v2/public/handles/{handle}/pages | pages.read (GET), pages.write (POST) |
/v2/public/handles/{handle}/pages/{pageSlug} | pages.write (PUT, DELETE) |
/v2/public/handles/{handle}/pages/{pageSlug}/publish | pages.write |
/v2/public/handles/{handle}/pages/{pageSlug}/preview | pages.read |
/v2/public/handles/{handle}/site-structure/campaigns/{campaignId} | pages.read (GET), pages.write (PUT) |
/v2/public/handles/{handle}/site-structure/campaigns/{campaignId}/publish | pages.write |
/v2/public/handles/{handle}/function-bindings | Public metadata discovery (no PAT required) |
/v2/public/handles/{handle}/function-bindings/mcp | mcp.connect plus binding.invoke:{bindingKey} or skill.invoke:{skillKey} |
/v2/public/handles/{handle}/function-bindings/{bindingKey}/invoke | mcp.connect plus binding.invoke:{bindingKey} or skill.invoke:{skillKey} |
/v2/handles/{handle}/connectors | mcp.connect plus connectors.read |
/v2/handles/{handle}/connectors/{connectorId} | mcp.connect plus connectors.read |
/v2/handles/{handle}/connectors/{connectorId}/search | mcp.connect plus connectors.read plus context_store.search |
/v2/mcp/{handle}/context-store/search | mcp.connect plus context_store.search |
/v2/mcp/{handle}/context-store/status | mcp.connect plus context_store.search |
/v2/mcp/{handle}/context-store/sources/{sourceId}/sync | mcp.connect plus context_store.manage |
Webhook note: /v2/public/handles/{handle}/webhooks/{subscriptionId}/test returns 202 when the delivery is queued. Your automation should still verify sink logs or downstream status before treating the test as successful.
Context Store refresh note: Webhook receivers and external automations can call the MCP sync route after verifying an event. This requests an async refresh; it does not ingest webhook payloads directly into Context Store.
Best practices
One token per system
Give your CI pipeline one token, your dashboard another, and your webhook processor a third. If one is compromised, you can revoke it without affecting the others.
Minimal scopes
A dashboard that only reads analytics should not have
links.write.Never commit secrets
Store PATs in environment variables or a secrets manager. Never hardcode them in source files.
Rotate regularly
Create a new token, update your systems, then revoke the old one.
Common errors
| Code | Error | Cause | |---|---|---| | 401 | missing_bearer_token | No Authorization header provided | | 401 | invalid_token | Token format is wrong or the secret does not match | | 403 | insufficient_scope | Token does not have the required scope for this endpoint | | 403 | insufficient_role | Caller does not have OPERATOR or higher role to manage tokens | | 404 | not_found | Token does not exist (already revoked or never created) |
Related
Choose the right token model for each workflow.
API Auth and Error ModelAuth modes, error handling, and retry logic
Webhook DeliveryDelivery guarantees, retries, and failure debugging
Context Store ConnectorsReplicated connector context for agents
API Endpoint Coverage MapFull endpoint reference
TroubleshootingDebug common issues
Updated Jun 19, 2026
