Delegated credentials
Every request goes to your tenant’s own host, https://<tenant id>.atlanticagenticlabs.com, and is scoped to that tenant by row-level security. The examples read AAL_TENANT, AAL_KEY and your Access service token from the environment: see Authentication.
OAuth authorisation server metadata (RFC 8414)
Section titled “OAuth authorisation server metadata (RFC 8414)”GET /.well-known/oauth-authorization-server
Authentication: A person’s session, or a machine key with your Access service token, as the route’s role allows. A route that approves, decides, pays or changes a limit refuses a machine key (person_required).
| Status | Meaning |
|---|---|
| 200 | OK: the JSON document this route reads. |
| 4XX | Refused: {error, message} with a fixed error code, listed under Errors. |
curl "https://$AAL_TENANT.atlanticagenticlabs.com/.well-known/oauth-authorization-server" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET"import os
import httpx
headers = { "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"],}r = httpx.get(f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/.well-known/oauth-authorization-server", headers=headers)r.raise_for_status()print(r.json())const res = await fetch( `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/.well-known/oauth-authorization-server`, { headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, }, },);if (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);console.log(await res.json());Protected resource metadata for the hosted MCP (RFC 9728)
Section titled “Protected resource metadata for the hosted MCP (RFC 9728)”GET /.well-known/oauth-protected-resource
Authentication: A person’s session, or a machine key with your Access service token, as the route’s role allows. A route that approves, decides, pays or changes a limit refuses a machine key (person_required).
| Status | Meaning |
|---|---|
| 200 | OK: the JSON document this route reads. |
| 4XX | Refused: {error, message} with a fixed error code, listed under Errors. |
curl "https://$AAL_TENANT.atlanticagenticlabs.com/.well-known/oauth-protected-resource" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET"import os
import httpx
headers = { "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"],}r = httpx.get(f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/.well-known/oauth-protected-resource", headers=headers)r.raise_for_status()print(r.json())const res = await fetch( `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/.well-known/oauth-protected-resource`, { headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, }, },);if (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);console.log(await res.json());Approve a waiting sign-in
Section titled “Approve a waiting sign-in”POST /api/v1/oauth/approve
Authentication: A person’s session, or a machine key with your Access service token, as the route’s role allows. A route that approves, decides, pays or changes a limit refuses a machine key (person_required).
| Status | Meaning |
|---|---|
| 200 | OK: the request was carried out. The answer is JSON. |
| 4XX | Refused: {error, message} with a fixed error code, listed under Errors. |
curl -X POST "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/oauth/approve" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET"import os
import httpx
headers = { "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"],}r = httpx.post(f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/api/v1/oauth/approve", headers=headers)r.raise_for_status()print(r.json())const res = await fetch( `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/api/v1/oauth/approve`, { method: "POST", headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, }, },);if (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);console.log(await res.json());Record an MCP client’s authorisation request, for a person to approve
Section titled “Record an MCP client’s authorisation request, for a person to approve”POST /api/v1/oauth/authorize
Authentication: A person’s session, or a machine key with your Access service token, as the route’s role allows. A route that approves, decides, pays or changes a limit refuses a machine key (person_required).
| Status | Meaning |
|---|---|
| 200 | OK: the request was carried out. The answer is JSON. |
| 4XX | Refused: {error, message} with a fixed error code, listed under Errors. |
curl -X POST "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/oauth/authorize" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET"import os
import httpx
headers = { "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"],}r = httpx.post(f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/api/v1/oauth/authorize", headers=headers)r.raise_for_status()print(r.json())const res = await fetch( `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/api/v1/oauth/authorize`, { method: "POST", headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, }, },);if (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);console.log(await res.json());Decline a waiting sign-in
Section titled “Decline a waiting sign-in”POST /api/v1/oauth/deny
Authentication: A person’s session, or a machine key with your Access service token, as the route’s role allows. A route that approves, decides, pays or changes a limit refuses a machine key (person_required).
| Status | Meaning |
|---|---|
| 200 | OK: the request was carried out. The answer is JSON. |
| 4XX | Refused: {error, message} with a fixed error code, listed under Errors. |
curl -X POST "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/oauth/deny" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET"import os
import httpx
headers = { "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"],}r = httpx.post(f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/api/v1/oauth/deny", headers=headers)r.raise_for_status()print(r.json())const res = await fetch( `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/api/v1/oauth/deny`, { method: "POST", headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, }, },);if (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);console.log(await res.json());Start a device sign-in (RFC 8628)
Section titled “Start a device sign-in (RFC 8628)”POST /api/v1/oauth/device/code
Authentication: A person’s session, or a machine key with your Access service token, as the route’s role allows. A route that approves, decides, pays or changes a limit refuses a machine key (person_required).
| Status | Meaning |
|---|---|
| 200 | OK: the request was carried out. The answer is JSON. |
| 4XX | Refused: {error, message} with a fixed error code, listed under Errors. |
curl -X POST "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/oauth/device/code" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET"import os
import httpx
headers = { "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"],}r = httpx.post(f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/api/v1/oauth/device/code", headers=headers)r.raise_for_status()print(r.json())const res = await fetch( `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/api/v1/oauth/device/code`, { method: "POST", headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, }, },);if (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);console.log(await res.json());The sign-in a person is being asked to approve
Section titled “The sign-in a person is being asked to approve”GET /api/v1/oauth/pending
Authentication: A person’s session, or a machine key with your Access service token, as the route’s role allows. A route that approves, decides, pays or changes a limit refuses a machine key (person_required).
| Status | Meaning |
|---|---|
| 200 | OK: the JSON document this route reads. |
| 4XX | Refused: {error, message} with a fixed error code, listed under Errors. |
curl "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/oauth/pending" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET"import os
import httpx
headers = { "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"],}r = httpx.get(f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/api/v1/oauth/pending", headers=headers)r.raise_for_status()print(r.json())const res = await fetch( `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/api/v1/oauth/pending`, { headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, }, },);if (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);console.log(await res.json());Register an MCP client (RFC 7591)
Section titled “Register an MCP client (RFC 7591)”POST /api/v1/oauth/register
Authentication: A person’s session, or a machine key with your Access service token, as the route’s role allows. A route that approves, decides, pays or changes a limit refuses a machine key (person_required).
| Status | Meaning |
|---|---|
| 201 | Created: the new resource, as JSON. |
| 4XX | Refused: {error, message} with a fixed error code, listed under Errors. |
curl -X POST "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/oauth/register" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET"import os
import httpx
headers = { "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"],}r = httpx.post(f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/api/v1/oauth/register", headers=headers)r.raise_for_status()print(r.json())const res = await fetch( `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/api/v1/oauth/register`, { method: "POST", headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, }, },);if (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);console.log(await res.json());Revoke a token and everything issued with it (RFC 7009)
Section titled “Revoke a token and everything issued with it (RFC 7009)”POST /api/v1/oauth/revoke
Authentication: A person’s session, or a machine key with your Access service token, as the route’s role allows. A route that approves, decides, pays or changes a limit refuses a machine key (person_required).
| Status | Meaning |
|---|---|
| 200 | OK: the request was carried out. The answer is JSON. |
| 4XX | Refused: {error, message} with a fixed error code, listed under Errors. |
curl -X POST "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/oauth/revoke" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET"import os
import httpx
headers = { "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"],}r = httpx.post(f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/api/v1/oauth/revoke", headers=headers)r.raise_for_status()print(r.json())const res = await fetch( `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/api/v1/oauth/revoke`, { method: "POST", headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, }, },);if (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);console.log(await res.json());The scopes a person can delegate
Section titled “The scopes a person can delegate”GET /api/v1/oauth/scopes
Authentication: A person’s session, or a machine key with your Access service token, as the route’s role allows. A route that approves, decides, pays or changes a limit refuses a machine key (person_required).
| Status | Meaning |
|---|---|
| 200 | OK: the JSON document this route reads. |
| 4XX | Refused: {error, message} with a fixed error code, listed under Errors. |
curl "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/oauth/scopes" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET"import os
import httpx
headers = { "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"],}r = httpx.get(f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/api/v1/oauth/scopes", headers=headers)r.raise_for_status()print(r.json())const res = await fetch( `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/api/v1/oauth/scopes`, { headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, }, },);if (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);console.log(await res.json());Exchange an approved grant for a token
Section titled “Exchange an approved grant for a token”POST /api/v1/oauth/token
Authentication: A person’s session, or a machine key with your Access service token, as the route’s role allows. A route that approves, decides, pays or changes a limit refuses a machine key (person_required).
| Status | Meaning |
|---|---|
| 200 | OK: the request was carried out. The answer is JSON. |
| 4XX | Refused: {error, message} with a fixed error code, listed under Errors. |
curl -X POST "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/oauth/token" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET"import os
import httpx
headers = { "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"],}r = httpx.post(f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/api/v1/oauth/token", headers=headers)r.raise_for_status()print(r.json())const res = await fetch( `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/api/v1/oauth/token`, { method: "POST", headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, }, },);if (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);console.log(await res.json());A person’s live delegated tokens
Section titled “A person’s live delegated tokens”GET /api/v1/oauth/tokens
Authentication: A person’s session, or a machine key with your Access service token, as the route’s role allows. A route that approves, decides, pays or changes a limit refuses a machine key (person_required).
| Status | Meaning |
|---|---|
| 200 | OK: the JSON document this route reads. |
| 4XX | Refused: {error, message} with a fixed error code, listed under Errors. |
curl "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/oauth/tokens" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET"import os
import httpx
headers = { "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"],}r = httpx.get(f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/api/v1/oauth/tokens", headers=headers)r.raise_for_status()print(r.json())const res = await fetch( `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/api/v1/oauth/tokens`, { headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, }, },);if (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);console.log(await res.json());Revoke one of a person’s own tokens
Section titled “Revoke one of a person’s own tokens”DELETE /api/v1/oauth/tokens/{token_id}
Authentication: A person’s session, or a machine key with your Access service token, as the route’s role allows. A route that approves, decides, pays or changes a limit refuses a machine key (person_required).
| Parameter | In | Type | Required |
|---|---|---|---|
token_id |
path | string | yes |
| Status | Meaning |
|---|---|
| 200 | OK: the request was carried out. The answer is JSON. |
| 400 | Bad request, bad_query: a path or query parameter, or a body field, is missing or not valid. |
| 4XX | Refused: {error, message} with a fixed error code, listed under Errors. |
curl -X DELETE "https://$AAL_TENANT.atlanticagenticlabs.com/api/v1/oauth/tokens/TOKEN_ID" \ -H "Authorization: Bearer $AAL_KEY" \ -H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \ -H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET"import os
import httpx
headers = { "Authorization": f"Bearer {os.environ['AAL_KEY']}", "CF-Access-Client-Id": os.environ["CF_ACCESS_CLIENT_ID"], "CF-Access-Client-Secret": os.environ["CF_ACCESS_CLIENT_SECRET"],}r = httpx.delete(f"https://{os.environ['AAL_TENANT']}.atlanticagenticlabs.com/api/v1/oauth/tokens/TOKEN_ID", headers=headers)r.raise_for_status()print(r.json())const res = await fetch( `https://${process.env.AAL_TENANT}.atlanticagenticlabs.com/api/v1/oauth/tokens/TOKEN_ID`, { method: "DELETE", headers: { Authorization: `Bearer ${process.env.AAL_KEY}`, "CF-Access-Client-Id": process.env.CF_ACCESS_CLIENT_ID!, "CF-Access-Client-Secret": process.env.CF_ACCESS_CLIENT_SECRET!, }, },);if (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);console.log(await res.json());