We use tracking technologies for site analytics and, if you allow it, for non-personalized advertising. These are two separate choices and neither one is required to use the site.Analytics and advertising cookies are optional and separate. Privacy Policy
No eligible rate right now
Give your agent anonymous, claimable access to real-time Ethiopian bank exchange rates over a small, open protocol. No human account to start — discover the endpoints, fetch a token, and read the latest rates. Free by default.
The anonymous path mirrors the OAuth 2.0 JWT bearer grant (RFC 7523): an anonymous identity, an identity assertion exchanged for a Bearer token. An optional claim ceremony (like OAuth device authorization) lets a human bind their email to the agent. Every URL below is served by the API host you are configured against.
1 · Discover
Fetch https://exchange.et/.well-known/oauth-authorization-server to learn the exact endpoints, grant types, and the AUTH.md recipe.
2 · Identify
POST https://api.exchange.et/api/v1/agent/identity. You get a signed identity_assertion (a short-lived JWT) for the token endpoint.
3 · Token
POST https://api.exchange.et/api/v1/oauth2/token with the jwt-bearer grant to exchange your assertion for an access token.
4 · Claim (optional)
Start a claim ceremony and print the user_code — a human confirms it at /agent/claim to own the agent.
Like an OAuth 2.0 authorization server, the API publishes its metadata at the RFC 8414 well-known location. Your agent should always read this document instead of hardcoding endpoints — it is the source of truth and may change.
curl https://exchange.et/.well-known/oauth-authorization-server
curl -s https://exchange.et/.well-known/oauth-authorization-server | jq .The metadata advertises:
token_endpoint — where to exchange an identity assertion or approved claim for a Bearer tokenagent_auth.identity_endpoint — where to resolve an anonymous identity or start a claim ceremonyagent_auth.claim_endpoint — where an agent starts a claim ceremony (the human confirms on this site at /agent/claim)service_documentation — the AUTH.md recipe (below){
"issuer": "https://exchange.et",
"token_endpoint": "https://api.exchange.et/api/v1/oauth2/token",
"revocation_endpoint": "https://api.exchange.et/api/v1/oauth2/revoke",
"x_standards_profile": "RFC 8414-style discovery for the exchange.et agent-auth JWT-bearer-only profile — not a full OAuth 2.0 authorization server. No authorization_endpoint and no authorization-code / implicit response_type flow exist; the jwt-bearer and claim grants are exchanged directly at the token endpoint, so response_types_supported is intentionally omitted.",
"scopes_supported": ["rates:read"],
"token_endpoint_auth_methods_supported": ["none"],
"revocation_endpoint_auth_methods_supported": ["none"],
"grant_types_supported": [
"urn:ietf:params:oauth:grant-type:jwt-bearer",
"urn:workos:agent-auth:grant-type:claim"
],
"service_documentation": "https://exchange.et/auth.md",
"agent_auth": {
"identity_endpoint": "https://api.exchange.et/api/v1/agent/identity",
"claim_endpoint": "https://api.exchange.et/api/v1/agent/identity/claim",
"identity_types_supported": ["anonymous", "identity_assertion", "service_auth"],
"events_supported": ["agent_registered", "agent_claimed", "credential_revoked"],
"signing": "HS256 self-issued (symmetric AGENT_AUTH_SECRET); no public JWKS keys",
"claim_ttl_seconds": 1800,
"assertion_ttl_seconds": 3600,
"access_token_ttl_seconds": 21600
}
}The API publishes AUTH.md — a plain Markdown document that agents can curl and follow step by step. It is the same flow documented on this page, but machine-friendly and kept in lockstep with the backend. Treat it as the canonical recipe.
Fetch the recipe from the service_documentation URL advertised in the metadata (currently https://exchange.et/auth.md), or follow the interactive flow below. The recipe works for both scripts and humans.
Fetch the recipe
curl -s https://exchange.et/auth.mdThree calls and your agent can read real-time rates. No email, no API key dashboard — just an anonymous identity.
identity_assertion — a short-lived JWT your agent stores and presents at the token endpoint. The supported identity types are advertised by the discovery document.POST https://api.exchange.et/api/v1/agent/identity
curl -X POST https://api.exchange.et/api/v1/agent/identity \
-H 'Content-Type: application/json' \
-d '{"identity_type": "anonymous", "scope": "rates:read"}'{
"identity_type": "anonymous",
"identity_assertion": "eyJhbGciOiJIUzI1NiIs...",
"expires_in": 3600,
"issuer": "https://exchange.et",
"scope": "rates:read",
"token_endpoint": "https://api.exchange.et/api/v1/oauth2/token"
}POST https://api.exchange.et/api/v1/oauth2/token
curl -X POST https://api.exchange.et/api/v1/oauth2/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \
-d 'assertion=<identity_assertion>'{
"access_token": "et_live_...",
"token_type": "Bearer",
"expires_in": 21600,
"scope": "rates:read",
"tier": "free"
}The identity and token endpoints are rate-limited to 20 requests/hour per IP — cache the token and reuse it instead of minting one on every call.
Use the Bearer token
curl -s 'https://exchange.et/api/v1/latest-rates' \
-H 'Authorization: Bearer <access_token>' | jq .Agents are anonymous by default. When you want a person to own the agent — to manage it, recover it, or tie it to an account — that person claims it with the user code the agent prints.
Requesting a service_auth identity returns a short-lived user_code and a verification URL. The agent displays them:
POST https://api.exchange.et/api/v1/agent/identity
curl -X POST https://api.exchange.et/api/v1/agent/identity \
-H 'Content-Type: application/json' \
-d '{"identity_type": "service_auth", "login_hint": "you@example.com"}'Claim me at https://exchange.et/agent/claim?code=K7XQ-9MNPThe owner opens exchange.et/agent/claim, enters the code and their email, and confirms.
Go to the claim pageThe user_code is valid for a short window (see the claim TTL in the metadata), so only the person holding it can claim the agent. After approval the agent exchanges its claim_token at the token endpoint (claim grant) to mint its access token.
POST https://api.exchange.et/api/v1/oauth2/token
curl -X POST https://api.exchange.et/api/v1/oauth2/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=urn:workos:agent-auth:grant-type:claim' \
-d 'claim_token=<claim_token>' \
-d 'user_code=<user_code>'Claiming is optional. An agent that is never claimed continues to work anonymously on the Free tier with no personal data attached.
You can stop an agent at any time. Access tokens expire after a few hours, but revoke immediately if a token leaks.
expires_in (6 hours), so a leaked token stops working on its own within hours. Your agent stores its identity assertion and can mint a fresh token whenever it needs one.The discovery document advertises a revocation_endpoint (https://api.exchange.et/api/v1/oauth2/revoke). Call it with the access token to revoke immediately. Claimed agents can also be revoked from the owner's account. For anything else, email support@keydama.com with the agent's identity details.
POST https://api.exchange.et/api/v1/oauth2/revoke
curl -X POST https://api.exchange.et/api/v1/oauth2/revoke \
-H 'Content-Type: application/json' \
-d '{"token": "<access_token>"}'Both credentials are short-lived, so a long-running agent must renew before they expire — never after a 401.
The identity assertion lasts 1 hour and the access token 6 hours. Before the assertion expires, present it back to mint a fresh one:
POST https://api.exchange.et/api/v1/agent/identity
curl -X POST https://api.exchange.et/api/v1/agent/identity \
-H 'Content-Type: application/json' \
-d '{"identity_type": "identity_assertion", "id_jag": "<current assertion>"}'Exchange each fresh assertion for a new access token via the jwt-bearer grant. Once an assertion has already expired it cannot be rolled forward — mint a new anonymous identity (or restart the claim ceremony) and exchange again. Cache the token and re-mint a short safety margin before expires_in elapses.
/.well-known/oauth-authorization-server document is the authoritative source; reading it keeps your agent working across deployments and upgrades. The AUTH.md recipe is the companion walkthrough.Ready to connect your agent?
Your configured API host is api.exchange.et. Start at the metadata document or send your agent to the claim page.