Skip to content

Authentication

Every endpoint takes a bearer token generated in Portal → your workspace → API Token (left-hand menu).

Authorization: Bearer {api_token}

The API distinguishes two failures in a way that is easy to get backwards:

Situation Status
Header present, token invalid or revoked 401 Unauthorized
Header absent entirely 403 Forbidden
401 — token present but invalid
{
"error": {
"status_code": 401,
"message": "Unauthorized",
"detail": "No permission -- see authorization schemes"
}
}
403 — no Authorization header
{
"error": {
"status_code": 403,
"message": "Forbidden",
"detail": "Request forbidden -- authorization will not help"
}
}

A GET on a POST-only endpoint also returns 403, not 405. No endpoint returns 405.

Get application info is served without authentication — but only while the application is still open. The hosted form needs this to fetch its own schema, and it is what lets an applicant who dropped off return to the same link and finish.

Terminal window
# No Authorization header. 200 while the application is unfinished.
curl 'https://app.uppass.io/en/api/forms/{form_slug}/applied-forms/{slug}/info/'
Application state Unauthenticated GET .../info/
Created, not yet submitted Returns the application
Submitted Requires the API token
Deleted 404 Not Found — permanently removed

So the exposure is bounded: a slug reaches an in-progress form and nothing else. Results, document images and screening outcomes are never readable this way — those come from Get application result, which always enforces the token.

Endpoint Token required
POST .../create/ Yes
GET .../result/ Yes
POST .../submit/ Yes
POST .../hook-submit/ Yes
GET .../info/ Only once submitted. A deleted application is 404 for everyone.

Webhooks carry the Bearer secret you configured in Portal → Connect → Add Webhook. Rejecting a mismatch is the only thing authenticating the caller.

Authorization: Bearer {webhook_secret}

Compare the header against the secret you stored, and answer 401 on a mismatch. There is no signature header; this comparison is the whole check.

See Webhooks for the rest of the receiver contract.