Digitalyser.io for developers
Guides

Choose your credential

Three credentials exist. Picking the wrong one is the most common way to lose an afternoon.

Digitalyser.io issues three kinds of credential. They are not interchangeable, and the failure mode when you pick wrong is quiet: the call authenticates, then refuses.

The short answer

You are…UseLooks like
An AI client acting for a person (Claude, ChatGPT, Cursor)Agent token, via OAuth consentdga_…
A server, script, or automation platform (n8n, Make, cron)Derived project tokendga_…
The dashboard, in a browser sessionSession JWT — not for you
Calling the REST surface without capabilitiesScoped API keyrk_…

A scoped API key opens no capability. This is the single most common wrong turn. An rk_ key authenticates the transport, and that is all it does — capabilities refuse it outright. The reason is structural, not a missing feature: a capability derives its project from the credential, and an API key is scoped to an organisation, not to a project. Honouring it would mean taking the project from a parameter, which is exactly the tenant-isolation hole the whole model exists to close.

Agent token — dga_

The only credential that opens capabilities. It always carries exactly one project. There are two ways to get one, and they differ only in who is present.

For AI clients. Obtained by the client, never by copy-paste: the user starts the connection from their tool, lands on a consent screen, picks one project, and ticks what the agent may do. Access tokens last an hour; a rotating refresh token (dgr_) keeps the connection alive for thirty days.

Without a person — derived project token

For servers, schedulers and automation platforms. No browser, no consent screen.

  1. An organisation administrator creates a service key for the organisation.
  2. They derive one token per project from it. The secret is returned once, at creation.
  3. Your system sends that token.
curl -X POST \
  https://app.digitalyser.io/api/organizations/$ORG/agent-service-keys/$KEY/tokens \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"projectId":"…"}'

Revoking the service key revokes every token derived from it, in one gesture.

Sending it

Authorization: Bearer dga_…, or the x-agent-token header.

One token, one project — for machines exactly as for people. An agency following several brands derives one token per client, so a workflow wired for one client cannot reach another's data. That uniformity is deliberate: there is no "machine mode" with weaker isolation.

Scoped API key — rk_

Created by an organisation administrator, scoped at issue time from the permission catalogue. It authenticates the REST surface for endpoints that are not capabilities. It carries only the permissions it was given, and — as the warning above says — it opens no capability.

Send it as Authorization: Bearer rk_….

A key in a browser is a leaked key. The REST surface is server-to-server only and does not enable permissive CORS — call it from your backend, never from a page.

Session JWT

Issued by the dashboard for a signed-in browser session. It authenticates the transport but opens no capability: presenting one to the MCP endpoint returns 401 with a message saying exactly that. If you are reading this page, this is not the credential you want.

What a wrong choice looks like

Present anything the MCP endpoint does not recognise and you get:

HTTP/2 401
WWW-Authenticate: Bearer error="invalid_token", resource_metadata="https://app.digitalyser.io/.well-known/oauth-protected-resource/api/mcp"

{
  "message": "Unrecognized credential for the MCP endpoint. Capabilities require an agent project token — send it as \"Authorization: Bearer dga_…\" or in the \"x-agent-token\" header. A JWT or API key authenticates the transport but opens no capability.",
  "error": "Unauthorized",
  "statusCode": 401
}

The WWW-Authenticate header is the useful part: it points at the resource metadata your client needs to start the authorisation flow. A conforming MCP client reads it and re-authorises on its own.

On this page