Skip to content

Ask for a sign-in link, as an AI assistant without a browser

OpenAPI JSON
POST
/v1/device/code
curl --request POST \
--url https://api.eu.apigami.com/v1/device/code \
--header 'Content-Type: application/json' \
--data '{ "agent_name": "AI agent" }'

Opens an agent sign-in: the words of RFC 8628, without its grant. Give the person verification_uri_complete and ask them to check that the page shows user_code; they sign in on https://app.apigami.com/agent, from any device, and approve. Then poll POST /v1/device/token with device_code. The body is read as JSON, even without a Content-Type, or as a form; grant_type and client_id are ignored. Guide, with a polling loop and the settings of each MCP client: https://www.apigami.com/docs/mcp/#agent-sign-in

Media typeapplication/json
object
agent_name

How the person will recognise you on the page and in their account: “ on ”. Letters, digits, space and . _ ( ) -, never a domain nor the word Apigami.

string
default: AI agent <= 60 characters /^[A-Za-z0-9 ._()-]{1,60}$/

The link to give the person, and what to poll with.

Media typeapplication/json
object
device_code
required

What you poll with. Keep it to yourself: whoever holds it collects the token once the person approved.

string
user_code
required

Eight letters in two groups. The page shows it too, for the person to compare.

string
verification_uri
required
string format: uri
verification_uri_complete
required

The link to give the person.

string format: uri
expires_in
required

Seconds the person has to decide: 900.

integer
interval
required

Seconds to wait between two polls.

integer
message
required

What to do next, in English.

string
Example
{
"device_code": "p3Qx…",
"user_code": "WDJB-MJHT",
"verification_uri": "https://app.apigami.com/agent",
"verification_uri_complete": "https://app.apigami.com/agent?code=WDJB-MJHT",
"expires_in": 900,
"interval": 5,
"message": "Give the user this link and ask them to check that the page shows the code WDJB-MJHT. …"
}

agent_name breaks the rule the description states.

Media typeapplication/json
object
error
required
string
Allowed values: invalid_request authorization_pending slow_down access_denied expired_token invalid_grant too_many_requests
error_description
required

What to do next, in English.

string
interval

With authorization_pending and slow_down: the seconds to wait before polling again.

integer
Example
{
"error": "invalid_request",
"error_description": "agent_name takes 1 to 60 characters among letters, digits, space and . _ ( ) -, and names neither a domain nor Apigami: use \"<client> on <machine or project>\", for example \"Claude Code on ada-laptop\"."
}

Too many requests from this network, with Retry-After. Keep polling the request you already have instead of opening another.

Media typeapplication/json
object
error
required
string
Allowed values: invalid_request authorization_pending slow_down access_denied expired_token invalid_grant too_many_requests
error_description
required

What to do next, in English.

string
interval

With authorization_pending and slow_down: the seconds to wait before polling again.

integer
Example
{
"error": "too_many_requests",
"error_description": "Too many agent sign-in requests from this network. Retry after 60 s. Meanwhile keep polling the request you already have instead of opening a new one."
}