This page documents all request and response schemas used by the ATH protocol API. The canonical machine-readable schemas are available as:

Discovery

DiscoveryDocument

Returned by GET /.well-known/ath.json.
{
  "ath_version": "0.1",
  "gateway_id": "ath-gateway.example.com",
  "agent_registration_endpoint": "https://ath-gateway.example.com/ath/agents/register",
  "supported_providers": [ProviderInfo]
}
FieldTypeRequiredDescription
ath_versionstringYesProtocol version
gateway_idstringYesGateway identifier
agent_registration_endpointstring (URI)YesURL for agent registration
supported_providersProviderInfo[]YesAvailable providers

ProviderInfo

{
  "provider_id": "example-mail",
  "display_name": "Example Mail",
  "categories": ["email", "productivity"],
  "available_scopes": ["mail:read", "mail:send", "mail:delete"],
  "auth_mode": "OAUTH2",
  "agent_approval_required": true
}
FieldTypeRequiredDescription
provider_idstringYesUnique provider identifier
display_namestringYesHuman-readable name
categoriesstring[]NoProvider categories
available_scopesstring[]YesScopes that can be requested
auth_modestringYesAuthentication mode (e.g. "OAUTH2")
agent_approval_requiredbooleanYesWhether registration is required

Registration

AgentRegistrationRequest

Sent to POST /ath/agents/register.
{
  "agent_id": "https://travel-agent.example.com/.well-known/agent.json",
  "agent_attestation": "<signed JWT>",
  "developer": {
    "name": "Example Corp",
    "id": "dev-example-12345"
  },
  "requested_providers": [
    { "provider_id": "example-mail", "scopes": ["mail:read", "mail:send"] }
  ],
  "purpose": "Travel planning assistant",
  "redirect_uris": ["https://travel-agent.example.com/callback"]
}
FieldTypeRequiredDescription
agent_idstring (URI)YesAgent’s canonical URI
agent_attestationstring (JWT)YesSigned attestation token
developer.namestringYesDeveloper name
developer.idstringYesDeveloper identifier
requested_providersarrayYesProviders and scopes to request
purposestringNoHuman-readable purpose
redirect_urisstring[]NoOAuth callback URIs. If provided, validated by exact-match on authorization. If omitted, user_redirect_uri MUST be rejected

AgentRegistrationResponse

{
  "client_id": "ath_travelbot_001",
  "client_secret": "ath_secret_xxxxx",
  "agent_status": "approved",
  "approved_providers": [ProviderApproval],
  "approval_expires": "2027-01-01T00:00:00Z"
}
FieldTypeDescription
client_idstringUnique registration identifier
client_secretstringSecret for token exchange
agent_status"approved" | "pending" | "denied"Registration status
approved_providersProviderApproval[]Per-provider approval results
approval_expiresstring (ISO 8601)Expiration timestamp

ProviderApproval

{
  "provider_id": "example-mail",
  "approved_scopes": ["mail:read"],
  "denied_scopes": ["mail:send"],
  "denial_reason": "Send capability requires additional review"
}

Authorization

AuthorizationRequest

Sent to POST /ath/authorize.
{
  "client_id": "ath_travelbot_001",
  "agent_attestation": "<signed JWT>",
  "provider_id": "example-mail",
  "scopes": ["mail:read"],
  "user_redirect_uri": "https://travel-agent.example.com/callback",
  "state": "<random-state-string>",
  "resource": "https://api.example.com/v1"
}
FieldTypeRequiredDescription
client_idstringYesAgent’s client ID
agent_attestationstring (JWT)YesFresh attestation token
provider_idstringYesProvider to authorize
scopesstring[]YesScopes to request (within approved set)
user_redirect_uristring (URI)NoPost-consent redirect
statestringYesCSRF protection state (MUST have ≥128 bits of entropy)
resourcestring (URI)NoTarget resource server (RFC 8707)

AuthorizationResponse

{
  "authorization_url": "https://example.com/oauth/authorize?...&code_challenge=...&code_challenge_method=S256",
  "ath_session_id": "ath_sess_abc123"
}
FieldTypeDescription
authorization_urlstring (URI)OAuth consent URL with PKCE parameters
ath_session_idstringSession ID for token exchange

Token

TokenExchangeRequest

Sent to POST /ath/token. Requires both client_secret and a fresh agent_attestation for proof-of-possession.
{
  "grant_type": "authorization_code",
  "client_id": "ath_travelbot_001",
  "client_secret": "ath_secret_xxxxx",
  "agent_attestation": "<signed JWT>",
  "code": "<oauth-authorization-code>",
  "ath_session_id": "ath_sess_abc123"
}

TokenResponse

{
  "access_token": "ath_tk_xxxxxxxx",
  "token_type": "Bearer",
  "expires_in": 3600,
  "effective_scopes": ["mail:read"],
  "provider_id": "example-mail",
  "agent_id": "https://travel-agent.example.com/.well-known/agent.json",
  "scope_intersection": {
    "agent_approved": ["mail:read"],
    "user_consented": ["mail:read", "mail:send"],
    "effective": ["mail:read"]
  }
}

ScopeIntersection

{
  "agent_approved": ["mail:read"],
  "user_consented": ["mail:read", "mail:send"],
  "effective": ["mail:read"]
}
FieldTypeDescription
agent_approvedstring[]Scopes the service approved for this agent
user_consentedstring[]Scopes the user consented to
effectivestring[]The intersection (effective permissions)

Revocation

TokenRevocationRequest

Sent to POST /ath/revoke. Requires client authentication per RFC 7009.
{
  "client_id": "ath_travelbot_001",
  "client_secret": "ath_secret_xxxxx",
  "token": "ath_tk_xxxxxxxx"
}

Errors

ATHError

All error responses follow this structure:
{
  "code": "INVALID_ATTESTATION",
  "message": "Agent attestation JWT has expired",
  "details": {}
}
CodeHTTP StatusDescription
INVALID_ATTESTATION401Agent attestation JWT failed verification
AGENT_NOT_REGISTERED403Agent must register before authorizing
AGENT_UNAPPROVED403Agent registration was denied
PROVIDER_NOT_APPROVED403Agent not approved for this provider
SCOPE_NOT_APPROVED403Agent not approved for requested scopes
SESSION_NOT_FOUND400OAuth session not found
SESSION_EXPIRED400OAuth session has expired
STATE_MISMATCH400OAuth state parameter mismatch
TOKEN_INVALID401ATH access token is invalid
TOKEN_EXPIRED401ATH access token has expired
TOKEN_REVOKED401ATH access token has been revoked
AGENT_IDENTITY_MISMATCH403Agent ID in request does not match token binding
PROVIDER_MISMATCH403Provider in request does not match token binding
USER_DENIED403User denied the OAuth consent
OAUTH_ERROR502Upstream OAuth provider returned an error
INTERNAL_ERROR500Internal server error