Arbituro docs

API authentication

Every call carries a bearer token: an API key for a program that runs on its own, or an OAuth token for an app people sign in to. Either way, the call acts as one person in your workspace, with that person’s access.

Choose a way in

An API key
For a program that runs with nobody signed in, such as a nightly script or a CI job. It acts as the person who made it, in the one workspace it was made in.
An OAuth token
For an app or a command line tool that people sign in to with their own Arbituro account. It acts as the person who signed in, in every workspace they belong to.

Send either one in the Authorization header of every call:

Header
Authorization: Bearer <your API key or token>

Make an API key

  1. In Arbituro, open Settings, then Connections.
  2. Open Your API keys.
  3. Name the key for the program that will hold it, such as nightly-sync. A name can be up to 80 characters.
  4. Choose when it expires: in 30 days, in 90 days, in a year, or never.
  5. Choose Make the key.
  6. Copy the key, and put it where the program keeps its secrets. This is the only time the key is shown.
  • Anyone in a workspace can make keys. Each key belongs to the person who made it, and acts as them.
  • A key starts with sk_.
  • Your API keys lists your keys in that workspace, each with its name, a masked form of its value, when it expires and when it was last used.

What a key can reach

What you can reach
A key has your workspace role and your role in each project. If you can only view a project, the key can only read it. See People and roles.
One workspace
A key works only in the workspace you made it in. A project in another of your workspaces gets the same answer as a project that doesn’t exist.
The API alone
The Arbituro app and the MCP server refuse API keys.
While you belong
Arbituro checks your membership on every call. If you leave the workspace or are removed from it, your keys stop working at once, and a change to your role applies from the next call.

Revoke a key

In Your API keys, choose Revoke beside the key. It stops working within a minute.

  • A key also stops working when it expires.
  • You can revoke only your own keys. To stop someone else’s, remove them from the workspace, which stops every key they made in it.

Keep keys safe

  • Make one key for each program, named for it. The audit log then says which program made each call, and you can revoke one key without touching the others.
  • Choose the shortest expiry that suits the program.
  • Keep keys out of code and repositories. Store them in your CI’s secrets or a secrets manager.
  • Arbituro doesn’t store the keys themselves. They are held by Arbituro’s sign-in service, and the audit log names a key by its name and ID, never its value.

Sign people in with OAuth

If you’re building an app or a command line tool that people use with their own Arbituro account, sign them in with OAuth instead of asking them for a key. The token you get acts as that person in every workspace they belong to, and each call’s project decides which one it reaches.

  1. Call the API without a token. The answer is 401, and its WWW-Authenticate header names the API’s metadata document.
    Terminal
    curl -i https://app.arbituro.com/api/v1/projects/WEB/jobs
    
    HTTP/1.1 401 Unauthorized
    WWW-Authenticate: Bearer resource_metadata="https://app.arbituro.com/.well-known/oauth-protected-resource/api/v1"
  2. The metadata document names the sign-in server and the scopes it offers.
    https://app.arbituro.com/.well-known/oauth-protected-resource/api/v1
    {
      "resource": "https://app.arbituro.com/api/v1",
      "authorization_servers": [
        "https://signin.arbituro.com"
      ],
      "scopes_supported": [
        "openid",
        "profile",
        "email",
        "offline_access"
      ],
      "bearer_methods_supported": [
        "header"
      ]
    }
  3. The sign-in server publishes its endpoints at https://signin.arbituro.com/.well-known/oauth-authorization-server.
  4. Register your app, with a Client ID Metadata Document or by Dynamic Client Registration. See Register your app.
  5. Send the person to sign in with the authorization code flow and PKCE (S256). Ask for a token for the resource https://app.arbituro.com/api/v1, and include offline_access so you can refresh the token without asking them to sign in again.
    The sign-in address, split across lines
    https://signin.arbituro.com/oauth2/authorize
      ?response_type=code
      &client_id=<your client ID>
      &redirect_uri=<your redirect address>
      &scope=openid%20profile%20email%20offline_access
      &resource=https%3A%2F%2Fapp.arbituro.com%2Fapi%2Fv1
      &code_challenge=<your PKCE challenge>
      &code_challenge_method=S256
      &state=<a random value>
  6. Exchange the code at the token endpoint, with your PKCE verifier and the same resource.

A token made for the API works only at the API. Tokens made for the Arbituro app or the MCP server are refused here, and a token made for the API is refused at both.

Register your app

Your app registers itself with Arbituro’s sign-in server, so there is nothing to set up in Arbituro. Use a Client ID Metadata Document if you can publish a file at an HTTPS address you control, and Dynamic Client Registration if you can’t.

With a Client ID Metadata Document

Publish a JSON document about your app at an HTTPS address. That address is your app’s client ID, so send it as client_id when you send someone to sign in. The sign-in server reads the document then, and shows the person your app’s name when they approve it.

https://example.com/arbituro/client.json
{
  "client_id": "https://example.com/arbituro/client.json",
  "client_name": "Release board",
  "redirect_uris": [
    "https://example.com/arbituro/callback"
  ],
  "grant_types": [
    "authorization_code",
    "refresh_token"
  ],
  "response_types": [
    "code"
  ],
  "token_endpoint_auth_method": "none"
}
client_id string
The document’s own address, exactly as you publish it.
client_name string
Your app’s name, as people see it when they approve your app.
redirect_uris array
The addresses sign-in can send people back to. The redirect_uri you send has to match one of them exactly.
grant_types array
authorization_code to sign people in, and refresh_token to refresh their tokens.
response_types array
code, for the authorization code flow.
token_endpoint_auth_method string
none. An app registered this way has no client secret.

With Dynamic Client Registration

Send the same details, without client_id, to the sign-in server’s registration endpoint. The answer includes a client_id for your app. Keep it, and send it each time you send someone to sign in.

Terminal
curl -X POST https://signin.arbituro.com/oauth2/register \
  -H "Content-Type: application/json" \
  -d '{
  "client_name": "Release board",
  "redirect_uris": [
    "https://example.com/arbituro/callback"
  ],
  "grant_types": [
    "authorization_code",
    "refresh_token"
  ],
  "response_types": [
    "code"
  ],
  "token_endpoint_auth_method": "none"
}'

Troubleshooting

A 401 has no body, so check these in turn.

A key is refused

  • It expired or was revoked. Make a new one.
  • You left the workspace it was made in, or were removed from it.
  • The header doesn’t start with Bearer followed by a space.

A token is refused

The token was made for another resource, such as the MCP server, or the sign-in left the resource out. Ask for a token with the resource https://app.arbituro.com/api/v1.

Sign-in refuses your app

  • The redirect_uri you sent isn’t exactly one of your app’s redirect_uris.
  • Your metadata document’s client_id isn’t exactly the address it’s published at.
  • The sign-in server can’t read your metadata document. It has to be public, at an HTTPS address.

Your API keys says your account can’t hold a key

Sign out of Arbituro, sign in again, and try once more.

A project gets 404 with a key that works elsewhere

The project is in another workspace, or you aren’t a member of it. A key reaches only the workspace it was made in.

Something missing or wrong? Email support@arbituro.com.