Authentication

Bead APIs currently use the OAuth 2 Resource-Owner Password grant. Your client submits:

  • client_id and client_secret

  • the service-account username and password

  • the fixed scope string openid profile email

The server returns a short-lived bearer token, which you send in the Authorization header of every subsequent API request.


Token endpoints

Environment
URL
Token lifetime

Sandbox

https://identity.test.devs.beadpay.io/oauth/token

3600 s

Production

https://identity.beadpay.io/oauth/token

3600 s


Client IDs and scope

client_id

Intended use

Required scope

bead-terminal

Device-level calls (payments, webhooks)

openid profile email

bead-integrator

Entity-management calls (merchants, locations, terminals)

openid profile email

No other scopes are accepted at this time.


Obtain an access token

curl -X POST "https://identity.test.devs.beadpay.io/oauth/token" \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "grant_type=password" \
     -d "client_id=bead-integrator" \
     -d "client_secret=$CLIENT_SECRET" \
     -d "username=$USER_EMAIL" \
     -d "password=$USER_PASSWORD" \
     -d "scope=openid profile email"

Successful response

{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "token_type":   "Bearer",
  "expires_in":   3600,
  "scope":        "openid profile email"
}

Reuse the token until it expires, then request a new one. There is no refresh-token step in the password-grant flow.


Authorizing API calls

curl -X GET "$BEAD_API/Locations/{id}" \
     -H "Authorization: Bearer $ACCESS_TOKEN"

A 401 Unauthorized response means the token is missing, expired, or was generated with a different client_id than the endpoint expects.


Error responses

HTTP

error

Meaning / resolution

400

invalid_request

Malformed form data (missing field)

401

invalid_client

client_id or client_secret not recognised

401

invalid_grant

Wrong username or password

403

insufficient_scope

Scope must be exactly openid profile email


Best practices

  • Cache tokens in memory until expires_in − 60 s, then fetch a new one.

  • Separate secrets – keep sandbox and production credentials in different vault entries.

  • Store credentials securely – environment variables or a secret-manager vault, never in source control.

  • Plan ahead – future versions will add finer-grained scopes and may migrate to client-credentials for server-to-server integrations.

Last updated