Authentication
Every request to the Geopera API carries a Bearer token in the Authorization header:
Authorization: Bearer <token>There are two ways to get one — an OAuth2 / OIDC flow for human users and service clients, and an API key for machine-to-machine integrations. Both resolve to a principal with a set of scopes, and every operation checks the scope it needs before running.
OAuth2 / OIDC token endpoint
The platform exposes a standards-compliant OpenID Connect token endpoint, so most OAuth2 client libraries and existing geospatial tooling work without modification:
POST https://api.geopera.com/realms/public/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencodedTokens are short-lived JWTs (5 minutes), with a longer-lived refresh token (30
minutes). The discovery document, JWKS, userinfo, introspect, revoke, and logout endpoints live under the same /realms/public/protocol/openid-connect/ base.
Grant: password
Exchange a user’s credentials for a token:
curl -X POST https://api.geopera.com/realms/public/protocol/openid-connect/token \
-d grant_type=password \
-d username='[email protected]' \
-d password='••••••••'Grant: client_credentials (machine-to-machine)
Exchange an API key (as the client secret) for a token — the right flow for backend services and automation:
curl -X POST https://api.geopera.com/realms/public/protocol/openid-connect/token \
-d grant_type=client_credentials \
-d client_id=geopera \
-d client_secret='<your-api-key>'Grant: refresh_token
Exchange a refresh token for a fresh access token without re-sending credentials:
curl -X POST https://api.geopera.com/realms/public/protocol/openid-connect/token \
-d grant_type=refresh_token \
-d refresh_token='<refresh-token>'Token response
{
"access_token": "eyJhbGciOiJIUzI1Ni
...",
"token_type": "Bearer",
"expires_in": 300,
"refresh_token": "...",
"refresh_expires_in": 1800,
"scope": "..."
}API keys
API keys are issued per organization and are ideal for integrations that act on
behalf of the organization rather than a single user. An organization administrator
creates a key with the api_keys.create operation; the
key is shown once at creation time — store it securely.
A key can be presented two ways:
- As the
client_secretin theclient_credentialsgrant above (recommended — you get a short-lived JWT back), or - Directly as a Bearer token /
X-API-Keyheader for SDK and tooling conventions.
Each key carries a permission set (read / write / process) that maps to the scopes
its requests are allowed to use. Keys can be revoked at any time with api_keys.revoke.
Scopes
Authorization is expressed in a single currency: resource:action scopes. Each
operation declares the one scope it requires, and the check runs identically no matter
how the operation is invoked. Examples:
| Scope | Grants |
|---|---|
catalog:read | Search the imagery catalog |
orders:read / orders:write | View / place and manage orders |
items:read / items:write | Read / create, update, delete STAC items & assets |
processing:process | Create and dispatch processing jobs |
billing:read / billing:write | View balance & history / top up, manage payment methods |
uploads:write | Upload bring-your-own data |
shares:write | Create and revoke share links |
A wildcard form is honoured where appropriate: items:* grants every action on items, and *:read grants the read action across resources. The Operations Reference lists the exact scope each
operation requires.
Scope is the coarse gate. Within an operation, fine-grained ownership is still enforced — e.g. you can only read items in projects your organization is a member of, regardless of holding
items:read.
Principals
Every authenticated request resolves to a principal of one kind. The kind determines how scopes are derived:
| Kind | Used by | Authority |
|---|---|---|
human | A logged-in user (OIDC password grant) | The self-serve scope set for the user’s organization |
api_key | An organization API key | The key’s read / write / process permissions |
service | Internal/system callers | Full trust (not customer-facing) |
worker | Processing workers | A narrow, job-bound scope — register their own job’s outputs and nothing else |
All actions are attributed to a principal, and every write is recorded with its principal for audit and provenance.
Errors
401 Unauthenticated— missing or invalid token.403 Forbidden— authenticated, but the principal lacks the operation’s scope.
Both are returned as application/problem+json.