# auth.md ReplyNodes is a read-only data API for agents. You can use this document to obtain a workspace-scoped, read-only API key after a human approves the connection in their browser. ## 1. Discover You are an agent. This document is the ReplyNodes setup recipe. The API base URL is `https://api.replynodes.com`. `GET /v1/capabilities` is public: it lists the providers and routes you can call. A `401` from any data route means you need an API key. Discover the available read-only capabilities with: ```sh curl -i https://api.replynodes.com/v1/capabilities ``` ## 2. Start a claim Create a claim on the dashboard. The request body is optional; these fields identify the agent to the human and are limited to 64 characters. ```sh curl -i -X POST https://platform.replynodes.com/api/agent/claim \ -H 'Content-Type: application/json' \ -d '{"agent_name":"Claude Code","agent_platform":"claude-code"}' ``` The successful response is HTTP `201`: ```json { "claim_id": "clm_1f0c9a...", "device_code": "<43-char base64url secret — shown to the agent exactly once>", "user_code": "K7QM-3XRT", "verification_uri": "https://platform.replynodes.com/claim", "verification_uri_complete": "https://platform.replynodes.com/claim?claim_id=clm_...&code=K7QM-3XRT", "expires_in": 900, "interval": 3, "docs": "https://replynodes.com/auth.md" } ``` Save `claim_id`, `device_code`, and `interval` in memory or secure local state. Do not expose `device_code` to the human. Every POST body must be sent with `Content-Type: application/json`; a request with another or missing media type is rejected with HTTP `400` and `{"error":"invalid_request"}`. Bodies are capped at 2 KB. If starting a claim is rate-limited, the response is HTTP `429`: ```json {"error":"rate_limited"} ``` ## 3. Ask the human to approve Surface `verification_uri_complete` and `user_code` to the human in one message. Ask them to open `verification_uri_complete` and approve the request. First time on ReplyNodes? The page they land on asks them to create their workspace with Google or GitHub (the same buttons sign an existing account back in); no password is involved. An account that already has API keys keeps them: the approval never rotates a key. The code is already in that link; they only type it if the agent gave it to them separately. It goes into the page, never back to the agent. ## 4. Poll for the result Poll with the `claim_id` and `device_code` from the start response. Honor the returned `interval` (three seconds initially) between polls. ```sh curl -i -X POST https://platform.replynodes.com/api/agent/claim/token \ -H 'Content-Type: application/json' \ -d '{"claim_id":"clm_1f0c9a...","device_code":""}' ``` While the human has not approved, the response is HTTP `428`: ```json {"error":"authorization_pending","status":"pending","interval":3} ``` When approved and the workspace has no active key, the response is HTTP `200` and contains the new key exactly once: ```json {"status":"approved","key_state":"created","api_key":"rn_live_...","key_id":"...","key_prefix":"rn_live_xxxxxx","workspace_id":"...","api_base_url":"https://api.replynodes.com","usage":"Authorization: Bearer ","docs":"https://replynodes.com/auth.md"} ``` An unknown claim or device code returns HTTP `404`: ```json {"error":"invalid_claim"} ``` An expired or void claim returns HTTP `410`: ```json {"error":"expired_token","status":"expired"} ``` If the gateway is temporarily unavailable, the response is HTTP `503`; keep the claim and retry: ```json {"error":"temporarily_unavailable"} ``` After the key has been delivered, polling again returns HTTP `409` and never returns plaintext key material: ```json {"error":"already_delivered","status":"delivered","key_state":"existing_key","existing_key":{...},"dashboard_url":"https://platform.replynodes.com/api-keys"} ``` ## 5. Use the key Store the returned key securely and use it as a Bearer token against the read-only API. For example: ```sh export REPLYNODES_API_KEY='rn_live_...' curl -i https://api.replynodes.com/v1/capabilities \ -H "Authorization: Bearer ${REPLYNODES_API_KEY}" ``` Use `GET /v1/capabilities` to discover the available API capabilities. ## 6. Existing key `existing_key` means the workspace already has an active key. Nothing was rotated. Do not retry for a new key. Tell the user to copy it from `https://platform.replynodes.com/api-keys` or rotate it there deliberately. ## Errors A malformed request (bad JSON, wrong or missing `Content-Type`, oversized body) returns HTTP `400` with `{"error":"invalid_request"}`. ## Security and limits - Store the key in an environment variable or another secure secret store. - Never echo the key into chat, logs, or issues. - The key is workspace-scoped and read-only. - The human's browser never displays the API key. - There is one active key per workspace. - A claim is valid for 15 minutes. - For an unknown or expired claim, start over with a new claim.