B2B Auth — obtaining and using API credentials
Calls into the Ark Platform business APIs (accounts, parties, cards, payments,
…) are authorised as applications, not users. The platform deliberately
rejects user-interactive ("sign in with Microsoft") tokens on these routes — a
plain az login will not work. You authenticate by minting a token via the
OAuth 2.0 client-credentials flow in Microsoft Entra ID, then sending it as
a bearer token with a few tenant-routing headers.
This page is the end-to-end path: how to obtain a credential, mint a token, make a call, and read the most common rejections.
At a glance
Before your first call — obtaining a credential
A credential is the pair client_id + client_secret of an Entra app that
the Ark instance has explicitly authorised. There are six steps, split across
three roles. Steps 1–2 happen in your Azure tenant; steps 3–5 happen against
the Ark Platform admin API; step 6 is repeatable per developer.
| # | Who | Where | What |
|---|---|---|---|
| 1 | Your Azure admin | Entra ID (your tenant) | Create an app registration. Note its Application (client) ID and generate a client secret. |
| 2 | Your Azure admin | Entra ID (your tenant) | Assign the CLIENT app role of the Ark Platform API app registration (AUTH_MICROSOFT_ENTRA_API_ID) to the app from step 1. |
| 3 | An Ark admin (ADMIN role) | Ark Platform admin API | PUT /v1/admin/external-applications/{oAuthAppId} with {"slug":"<app-slug>"} — registers the Entra app with Ark. |
| 4 | An Ark admin (ADMIN role) | Ark Platform admin API | PUT /v1/admin/clients/{slug} with {"clientStatus":"ACTIVE","brandStatus":"ACTIVE"} — creates the client/brand tenant (slug e.g. client1-brand2) that step 5 authorises the app against. The client/brand must exist before it can be mapped. |
| 5 | An Ark admin (ADMIN role) | Ark Platform admin API | PUT /v1/admin/external-applications/{oAuthAppId}/clients/{clientBrandSlug} — authorises the app for a specific client/brand. {clientBrandSlug} must match the {slug} created in step 4. |
| 6 | The developer making calls | Their terminal / app | Use the client_id + client_secret from step 1 to mint a token (see Minting a token). |
oAuthAppId in steps 3 and 5 is the Application (client) ID (a UUID) from
step 1. Ark never stores the client secret — only the mapping oAuthAppId → client/brand. The secret lives in Entra; you, the customer, control it.
Ark is self-hosted in your Azure environment (see the hosting minimum
requirements). Steps 1–2
are run by your Azure admin in your tenant. Steps 3–5 are run by
whoever holds the ADMIN role on your Ark instance.
References for steps 1–2:
- Microsoft Entra: register an application
- Microsoft Entra: app roles and assign users
- OAuth 2.0 client-credentials grant flow
API reference: Administration Clients (step 4) and Administration External Applications (steps 3 and 5).
Minting a token
curl -s -X POST https://login.microsoftonline.com/$TENANT_ID/oauth2/v2.0/token \
-d "grant_type=client_credentials" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET" \
-d "scope=api://$ARK_API_ID/.default" \
| jq -r .access_token
| Variable | Where it comes from |
|---|---|
TENANT_ID | Your Entra tenant id. |
CLIENT_ID | The Application (client) ID from step 1. |
CLIENT_SECRET | The client secret from step 1. Keep in a secret store (Key Vault, 1Password, …). |
ARK_API_ID | The Application (client) ID of the Ark Platform API app registration (AUTH_MICROSOFT_ENTRA_API_ID). |
The response is a JWT (access_token). Tokens are short-lived (typically one
hour) — re-mint as needed.
az login won't workaz account get-access-token --resource api://$ARK_API_ID only yields an
accepted token when you ran az login --service-principal … with the
credential from step 1. A plain user az login produces a delegated user
token with no appid claim → 403 (see Troubleshooting).
Calling an endpoint
Send the token as a bearer header. Most business endpoints additionally
require the tenant-routing headers clientid and brandid; party-scoped
endpoints also require partyid.
GET /v1/parties/{partyId}
Host: <your-ark-host>
Authorization: Bearer <access_token>
clientid: <client-uuid>
brandid: <brand-uuid>
partyid: <party-uuid>
| Header | When | Notes |
|---|---|---|
Authorization | Always | Bearer <jwt> from Minting a token. |
clientid | Business endpoints | The UUID of the client whose data you're acting on. Must match a mapping from step 5. |
brandid | Business endpoints | The UUID of the brand under that client. |
partyid | Party-scoped endpoints (parties, cards, accounts) | The UUID of the party. |
customerid | Customer-scoped endpoints | Where applicable. |
The exact required headers per endpoint are declared in the OpenAPI specs (see API Reference).
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
401 Unauthorized | Token missing, malformed, expired, signed by a tenant Ark doesn't trust, or audience mismatch. | Re-mint the token. Check $TENANT_ID matches the tenant Ark is configured for and scope is api://$ARK_API_ID/.default. |
403 AUT001002 External application does not have access to the requested resource | One of: (a) the token has no appid claim — it is a user token, not a client-credentials token; (b) the app from step 1 has not been registered + mapped, or its client/brand was never created (steps 3–5); (c) the app is registered but not mapped to the clientid/brandid you sent. | Confirm the token was minted via client-credentials. Confirm an admin completed steps 3 through 5 against the exact client/brand slug you're using. |
401 GEN001006 | RolesGuard rejection — the token is valid but the app doesn't carry the CLIENT role. | Re-do step 2. The role must be the CLIENT app role on the Ark Platform API app registration. |
Try it from the docs
Every endpoint page in the API Reference has a
Try it panel. Mint a token as above, paste it into the bearer field, fill
the clientid/brandid (+ partyid where applicable) headers, and send.
Related
- Admin Authentication — the same OAuth flow, but with the
ADMINrole for instance configuration APIs. - Administration Clients API — endpoint used in step 4 to create the client/brand tenant.
- Administration External Applications API — endpoints used in steps 3 and 5.
- Minimum Requirements — the hosting model that puts steps 1–2 in your tenant.