Hadrian is experimental alpha software. Do not use in production.
Hadrian

Oauth

OAuth-style PKCE flow for issuing user-scoped API keys to external apps. The user grants consent in the Hadrian UI; the external app exchanges the resulting code at /oauth/token for an API key bound to that user.

Serve the OAuth 2.0 Authorization Server Metadata document.

GET
/.well-known/oauth-authorization-server
AuthorizationBearer <token>

API key authentication using Bearer token format

In: header

Response Body

application/json

application/json

curl -X GET "https://loading/.well-known/oauth-authorization-server"
{
  "authorization_endpoint": "string",
  "code_challenge_methods_supported": [
    "string"
  ],
  "grant_types_supported": [
    "string"
  ],
  "issuer": "string",
  "response_types_supported": [
    "string"
  ],
  "scopes_supported": [
    "string"
  ],
  "service_documentation": "string",
  "token_endpoint": "string",
  "token_endpoint_auth_methods_supported": [
    "string"
  ]
}
{
  "error": {
    "code": "budget_exceeded",
    "message": "Budget limit exceeded for monthly period",
    "param": null,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "type": "invalid_request_error"
  }
}
POST
/admin/v1/oauth/authorize
AuthorizationBearer <token>

API key authentication using Bearer token format

In: header

Request Body

application/json

app_name?string|null

Optional human-readable name of the requesting app, shown on the consent screen.

callback_url*string

Where the external app expects the user to land after consent. The exchange endpoint requires this exact same value when redeeming.

code_challenge*string

PKCE challenge supplied by the external app. RFC 7636 §4.1 mandates 43–128 characters for both the verifier and (by extension) the S256 / plain challenges.

code_challenge_method*string

Method used to derive the challenge. S256 unless auth.oauth_pkce.allow_plain_method is set.

Value in"S256" | "plain"
key_options?

User's choices for the API key that will be issued on exchange. Mirrors the fields shown in the self-service "Create API Key" modal.

Response Body

application/json

application/json

application/json

application/json

curl -X POST "https://loading/admin/v1/oauth/authorize" \  -H "Content-Type: application/json" \  -d '{    "callback_url": "string",    "code_challenge": "string",    "code_challenge_method": "S256"  }'
{
  "code": "string",
  "expires_at": "2019-08-24T14:15:22Z",
  "redirect_url": "string"
}
{
  "error": {
    "code": "budget_exceeded",
    "message": "Budget limit exceeded for monthly period",
    "param": null,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "type": "invalid_request_error"
  }
}
{
  "error": {
    "code": "budget_exceeded",
    "message": "Budget limit exceeded for monthly period",
    "param": null,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "type": "invalid_request_error"
  }
}
{
  "error": {
    "code": "budget_exceeded",
    "message": "Budget limit exceeded for monthly period",
    "param": null,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "type": "invalid_request_error"
  }
}
GET
/admin/v1/oauth/preflight
AuthorizationBearer <token>

API key authentication using Bearer token format

In: header

Query Parameters

callback_url*string

The callback URL the external app intends to use.

Response Body

application/json

application/json

application/json

application/json

curl -X GET "https://loading/admin/v1/oauth/preflight?callback_url=string"
{
  "callback_host": "string"
}
{
  "error": {
    "code": "budget_exceeded",
    "message": "Budget limit exceeded for monthly period",
    "param": null,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "type": "invalid_request_error"
  }
}
{
  "error": {
    "code": "budget_exceeded",
    "message": "Budget limit exceeded for monthly period",
    "param": null,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "type": "invalid_request_error"
  }
}
{
  "error": {
    "code": "budget_exceeded",
    "message": "Budget limit exceeded for monthly period",
    "param": null,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "type": "invalid_request_error"
  }
}

Exchange a PKCE authorization code for a user-scoped API key.

POST
/oauth/token
AuthorizationBearer <token>

API key authentication using Bearer token format

In: header

Request Body

application/json

code*string

The authorization code received via the callback URL. We generate 256-bit codes, so anything shorter than ~32 chars is definitely not one of ours; the upper bound just defends the deserializer.

code_challenge_method?null|PkceCodeChallengeMethod
code_verifier*string

The original PKCE verifier the external app generated. Length range matches RFC 7636 §4.1, which mandates 43–128 URL-safe characters.

Response Body

application/json

application/json

application/json

curl -X POST "https://loading/oauth/token" \  -H "Content-Type: application/json" \  -d '{    "code": "string",    "code_verifier": "string"  }'
{
  "key": "string",
  "key_id": "1e779c8a-6786-4c89-b7c3-a6666f5fd6b5",
  "key_prefix": "string"
}
{
  "error": {
    "code": "budget_exceeded",
    "message": "Budget limit exceeded for monthly period",
    "param": null,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "type": "invalid_request_error"
  }
}
{
  "error": {
    "code": "budget_exceeded",
    "message": "Budget limit exceeded for monthly period",
    "param": null,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "type": "invalid_request_error"
  }
}