API reference
External apps
Plug your application into IntelligenceBox: it appears in the customer's sidebar and opens in place, already authenticated as whoever opened it. The launch hands you their API key, so your app talks to the box on their behalf — it sees exactly what they see, and nothing more.
Who this page is for
Whoever builds the external application. The customer connects it from their box under Automations → External app, and hands you a single value: the verification address, which is the same for every customer. There is no secret to configure — the key arrives with the launch itself.How it works#
Four steps. The box does the first two, your application does the rest.
- 1
The user opens your app from the menu
The box mints an API key for that person and asks the auth service for a single-use ticket, good for 60 seconds and bound to that key. - 2
The box opens your SSO path in an iframe
You get a POST on the path you configured, carryingticket,apiKeyandapiBaseUrlin the body. Never a query string: a ticket in a URL would survive in history, referrer and logs. - 3
You redeem the ticket from your server
A POST to/api/integrations/embed/exchangewith the ticket, using theapiKeyyou just received as the bearer. It answers with who the user is. - 4
You open the session and use the key
Create your application session as you would with any SSO, and keep the API key to talk to the box — now or later, including when the user is not connected.
Redeeming the ticket#
/api/integrations/embed/exchangepublicConsumes a launch ticket and returns the identity of whoever opened the app.
Call this server to server, never from the browser. The bearer is the apiKey that arrived with the launch: the ticket is bound to that key, so whoever intercepted the ticket alone cannot redeem it.
# The key is the one that arrived in the same launch POST.
curl -X POST AUTH_URL/api/integrations/embed/exchange \
-H "Authorization: Bearer $API_KEY_FROM_THE_LAUNCH" \
-H "Content-Type: application/json" \
-d '{ "ticket": "THE_TICKET_FROM_THE_LAUNCH" }'Request body
AuthorizationstringrequiredBearer <apiKey>— the key received in the same launch POST. There is nothing to configure in advance.
ticketstringrequired- The
ticketfield you received on your SSO path. It is single-use: a second call with the same ticket fails.
Response
{
"user": {
"id": "cmlwjuy7e0000fiyvsdbo6mya",
"email": "laura@example.com",
"name": "Laura Bianchi"
},
"embed": { "key": "bluedesk", "name": "BlueDesk" },
"apiKey": {
"key": "boxe_9f3c…",
"persistent": true,
"issuedNow": false,
"header": "x-api-key"
},
"api": { "baseUrl": "https://box.example.com/api/public" }
}userobject- Who opened the app: id, email and name as the auth service knows them.
embedobject- The app key, so you can confirm you were opened as the app you think you are.
apiKey.keystring- Not in the response: you already have it from the launch. Put it in
x-api-keyon every call to the box API. api.baseUrlstringapiBaseUrlarrives with the launch and is the root to call: reverse proxies, tunnels and LAN boxes all differ. Check it against the one you know for that customer before using it — it comes from a POST anyone can forge.
200Valid ticket: identity in the response.400The ticket or the key is missing.401Ticket expired, already used, or wrong key.403The account is not eligible to open this app.500The auth service is unreachable, or external apps are not configured on this box.
The API key#
One key per person, per installed app. It is not a service key: it is the person who opened your application.
It lasts
A later exchange for the same user returns the same key. Re-opening the app does not invalidate the one you are already using, so you can store it and work while the user is away — nightly syncs, webhooks, reminders.
It sees what the user sees
The key is not administrative access: every call is filtered through that person's own visibility, and through the workspace the app was opened from. That workspace is bound to the key — sending a different x-organization-id header does not move it elsewhere.
How it dies
The key stops working, immediately, when:
- the customer revokes access from the configuration page;
- the app is uninstalled from the box;
- the app is paused.
After a revocation, the new key arrives with the next launch — there is nothing to reconfigure. Handle a 401 by sending the user back through a launch, not by retrying the same key.
Using the key#
From here it is the ordinary public API: same authentication, same endpoints. The most useful thing to start with is a notification, because it reaches the person even when your app is closed.
curl -X POST BOX_URL/api/public/notifications \
-H "x-api-key: boxe_9f3c…" \
-H "Content-Type: application/json" \
-d '{
"title": "Pratica 4821 approvata",
"description": "Il documento e pronto per la firma.",
"type": "success",
"icon": "FileCheck",
"name": "BlueDesk"
}'The rest of the surface
Folders, documents, semantic search, assistants and conversations all work the same way with this key. AskGET /api/public/capabilities for the current list of what the customer's box exposes.Security rules#
Few, but not negotiable.
The key never touches the browser
It arrives in a POST to your server and must stay there. If it ends up in a JavaScript bundle, anyone can act as the user.
Neither does the API key
Treat it like the user's password: it stays on your backend, and calls to the box start there. A frontend that exposes it hands it to anyone who opens devtools.
Redeem the ticket exactly once
It is single-use by construction. If your SSO page double-renders or prefetches, the second attempt fails: redeem it server-side, not in a client effect.
Do not trust the iframe for identity
The only authoritative identity is the one the exchange returns. Anything arriving by postMessage or query string beyond the ticket is a hint, not proof.
When it does not work#
401 on exchange, with a ticket you just received
The ticket was already consumed (SSO page double-render), or you sent a bearer other than the apiKey that arrived in the same launch POST.
403 on exchange
The account does not meet the requirements the customer set on the app — email domain, verified address, brand.
401 on an API call that used to work
Access revoked, app paused or uninstalled. Start again from a launch.
The app does not appear in the customer's menu
That is visibility, decided on their configuration page: someone who cannot see it cannot open it either.