Skip to main content

Overview

Service tokens are long-lived API tokens scoped to a customer (organization) or a single seat (advertiser). Use them when the caller is not a human user — backend services, ETL jobs, agent runtimes, multi-tenant tools, partner integrations. They are distinct from personal API keys, which are bound to an individual user. Service tokens survive user offboarding, can be scoped down to a single seat with a specific role, and have explicit lifecycle controls (expiresInDays, archive).
Personal API keyService token
Tied to a user accountTied to a customer or seat
Revoked when user leavesSurvives user changes
One token per userMany per customer
Best for: dashboards, scripts you run as yourselfBest for: server-to-server, agents, multi-tenant tools
Both are bearer credentials — every request sends Authorization: Bearer scope3_<token>.

Token format

A service token is a single opaque string with three parts joined by underscores:
scope3_<accessClientId>_<accessClientSecret>
  • The scope3_ prefix lets us recognize the token at the edge.
  • accessClientId is a stable, non-secret identifier — safe to log, surface in admin UIs, and reference in audit trails.
  • accessClientSecret is the credential — only shown once, at creation.
The full token (fullToken field on the create response) is shown exactly once, on the response to POST /service-tokens. We store only a hash; we cannot show it to you again. If you lose it, revoke the token and create a new one.

Prerequisites

1

An admin or read-write API key

You need an existing credential with permission to manage tokens — a user API key from agentic.scope3.com/user-api-keys, or another service token with ADMIN role.
2

Decide the scope

Pick CUSTOMER (acts across every seat) or SEAT (limited to one advertiser). For seat-scoped tokens, you also choose a role (ADMIN, READ_WRITE, READ) and an expiry between 1 and 365 days.
3

A secret manager

Plan where you’ll store fullToken. Service tokens act on your organization’s behalf — keep them in Google Secret Manager, AWS Secrets Manager, HashiCorp Vault, or equivalent. Never commit them to git.
All examples below use:
BASE = https://api.agentic.scope3.com/api/v2
AUTH = Authorization: Bearer scope3_<your_token>
Service-token endpoints live under /api/v2/service-tokens, not under /api/buyer/... or /api/storefront/.... They are mounted on the v2 shared router because the same token-management surface works for buyer and storefront customers alike. Most other v2 endpoints sit under a buyer/storefront mount — service tokens are the exception.

Step 1: Create a service token

POST /service-tokens returns the new token, including the one-time-only fullToken field. Capture it before doing anything else.
curl -X POST "$BASE/service-tokens" \
  -H "Authorization: Bearer scope3_<your_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Nightly ETL — Snowflake export",
    "description": "Pulls reporting data into the warehouse every 02:00 UTC",
    "expiresInDays": 365,
    "scope": "CUSTOMER"
  }'
Response
{
  "id": "12345",
  "customerId": "cust_abc",
  "seatId": null,
  "userId": null,
  "name": "Nightly ETL — Snowflake export",
  "description": "Pulls reporting data into the warehouse every 02:00 UTC",
  "accessClientId": "ak_01HXYZ...",
  "fullToken": "scope3_ak_01HXYZ..._sk_live_9c8d7e6f...",
  "expiresAt": "2027-04-26T00:00:00.000Z",
  "createdAt": "2026-04-26T16:30:00.000Z",
  "role": null,
  "createdByUserId": "98765"
}
Capture fullToken and store it in your secret manager immediately. After this response, only accessClientId is retrievable.

Request body

FieldTypeRequiredNotes
namestringnoHuman-readable label, max 255 chars
descriptionstringnoFree-form, max 1000 chars
expiresInDaysintegerconditional1–365. Required when scope: SEAT
scopeenumnoCUSTOMER (default) or SEAT
seatNamestringconditionalRequired when scope: SEAT
seatTypeenumnoBUYER or ACTIVATION — disambiguates if multiple seats share a name
roleenumconditionalADMIN, READ_WRITE, or READ. Required when scope: SEAT

Step 2: List or fetch existing tokens

Use the list endpoint to see what tokens exist for your customer (or for a specific seat). The list view never includes the secret — only accessClientId, scope, expiry, and audit metadata.
curl "$BASE/service-tokens?take=50&skip=0" \
  -H "Authorization: Bearer scope3_<your_token>"
Query paramTypeDefaultNotes
seatIdstringFilter by seat
includeArchivedbooleanfalseInclude revoked tokens
takeinteger50Page size, max 100
skipinteger0Offset
To inspect a single token (for example, before extending its expiry):
curl "$BASE/service-tokens/12345" \
  -H "Authorization: Bearer scope3_<your_token>"
You can also rename a token or extend its expiry through the update endpoint. You cannot shorten the expiry through this endpoint — to invalidate a token sooner, archive it (Step 4).
curl -X PUT "$BASE/service-tokens/12345" \
  -H "Authorization: Bearer scope3_<your_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Nightly ETL — Snowflake export (renamed)",
    "expiresInDays": 365
  }'

Step 3: Rotate a token

Treat service tokens like any other long-lived credential and rotate on a schedule. The pattern is “create new, deploy, revoke old” — never edit the existing token in place.
1

Create the new token

POST /service-tokens with the same scope and role as the old one. Capture fullToken and id from the response.
2

Deploy to consumers

Update your secret manager and roll the new token out to every service that holds the old one.
3

Confirm rollout completed

Wait until you’ve confirmed all consumers have switched — for example, by checking deploy status, draining staging traffic, or watching error rates after a forced restart. Don’t revoke the old token until you’re sure nothing still depends on it.
4

Revoke the old token

DELETE /service-tokens/<old_id>. Any service still using the old token will start receiving 401 Unauthorized, which is your final signal that rollout missed somewhere.
Set expiresInDays to a value shorter than your rotation window so an unrotated token expires on its own — defense-in-depth for the case where a token is forgotten.

Step 4: Revoke a token

Revocation is a soft delete — the token stops authenticating immediately, but its audit row is preserved.
curl -X DELETE "$BASE/service-tokens/12345" \
  -H "Authorization: Bearer scope3_<your_token>"
Returns 204 No Content.
Rotate on suspected leak. If a token might have been exposed (CI log, shared screen, leaked dependency), revoke it via DELETE /service-tokens/:id immediately, then issue a replacement. Do not wait for confirmation.

Best practices

  • Use seat scope when possible. A SEAT-scoped token with READ role cannot move spend, even if exfiltrated. Default to least-privilege: pick the narrowest scope and lowest role that lets the integration do its job.
  • One token per workload. If two services have different lifecycles or different blast radii, give them separate tokens. That way a leak or rotation only affects one workload at a time.
  • Treat as a credential. Never commit tokens to git, never paste them into chat or email, never hard-code them in client-side bundles.
  • Multi-tenant tools have two patterns.
    • One token per managed seat. Create a SEAT-scoped token per child seat with the minimum role each integration needs. Best when child accounts have different administrators or you want clean per-tenant audit trails.
    • One customer-scoped token. Use scope: CUSTOMER and rely on per-request seat selection. Best when a single team owns automation across every child seat.
    • Either way, never share a single token across unrelated tenants — it conflates audit trails and forces a global revocation if any tenant is compromised.

Endpoint reference

All paths are relative to https://api.agentic.scope3.com/api/v2.
MethodPathPurpose
GET/service-tokensList service tokens
POST/service-tokensCreate a service token (returns fullToken once)
GET/service-tokens/:idGet a single service token
PUT/service-tokens/:idUpdate name, description, or extend expiry
DELETE/service-tokens/:idArchive (revoke) a service token

Authentication

Bearer token format, header conventions, and how personal API keys differ from service tokens.

Errors

Status codes and JSON error shapes returned by the service token endpoints — including auth and validation failures.