PostraDocsOpen Postra

Sign in with Postra (OAuth)

Use this when you build an app that works for other Postra users. Each user approves your app once. You get an access token for their workspace. You never see their API key or password.

To automate only your own workspace, you do not need this. Use your API key instead. See Developer settings.

The token starts with pos_. It works wherever an API key works: the Public API, the Node.js SDK and MCP.

At a glance

Authorisation page https://app.postra.co.uk/oauth/authorize
Token endpoint https://app.postra.co.uk/api/oauth/token
Grant type authorization_code only
Client authentication client_id and client_secret in the request body
PKCE Optional, S256 only
Scopes None
Refresh tokens None

1. Create your OAuth app

You need to be the workspace owner or an Admin, on a plan with the API.

  1. In Postra, open Settings → Developers → Apps.
  2. Click Create OAuth App.
  3. Fill in the form and click Create.
Field
App Name Required, up to 100 characters. Users see it on the consent screen.
Description Optional, up to 500 characters. Also on the consent screen.
Profile Picture Optional, from your media library.
Redirect URL Required. Postra sends users back here after they decide.

You get:

Copy the secret straight away. Postra shows it only once, after you create the app or rotate the secret. Keep it on your server.

Each workspace can have one OAuth app.

2. Send the user to the authorisation page

https://app.postra.co.uk/oauth/authorize?client_id=YOUR_CLIENT_ID&response_type=code&state=RANDOM_STATE
Parameter Required
client_id Yes Your Client ID
response_type Yes Must be code
state Recommended Any value. It comes back unchanged, so you can match the answer to the request.
code_challenge Optional PKCE: BASE64URL(SHA256(code_verifier)), 43 characters
code_challenge_method With code_challenge Must be S256. plain is not supported.

PKCE makes a stolen code useless: it can only be exchanged with the code_verifier that only your app holds.

If the user is not signed in to Postra, Postra asks them to sign in first and then shows the consent screen.

The screen shows your app’s name, description and picture, and says the app will be able to:

The user clicks Authorize or Deny.

Only the workspace owner or an Admin can approve. The token acts for the workspace that is selected in Postra at that moment.

4. Handle the redirect

Postra always sends the user to the Redirect URL saved in your app. A redirect_uri parameter is not used.

If the user approves:

https://your-app.example/callback?code=AUTHORISATION_CODE&state=RANDOM_STATE

If the user denies:

https://your-app.example/callback?error=access_denied&state=RANDOM_STATE

Check that state matches what you sent. The code works for 10 minutes and only once.

5. Exchange the code for a token

Call the token endpoint from your server. JSON and application/x-www-form-urlencoded bodies both work.

curl https://app.postra.co.uk/api/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "code": "AUTHORISATION_CODE",
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET"
  }'

If you sent a code_challenge in step 2, add "code_verifier": the string of 43 to 128 characters you hashed. Send it only then. A code_verifier for a code requested without a challenge is refused.

Answer:

{
  "id": "WORKSPACE_ID",
  "access_token": "pos_ACCESS_TOKEN",
  "token_type": "bearer"
}

id is the Postra workspace the token acts for. Store the token safely on your server.

6. Call the API

Send the token in the Authorization header as it is, without Bearer:

curl https://app.postra.co.uk/api/public/v1/integrations \
  -H "Authorization: pos_ACCESS_TOKEN"

With the Node.js SDK, pass the token where you would pass an API key:

const postra = new Postra('pos_ACCESS_TOKEN');

For MCP at https://app.postra.co.uk/api/mcp, send it as Authorization: Bearer pos_ACCESS_TOKEN.

What the token can do

There are no scopes. A token has the same access as the workspace’s API key, which is that of a workspace Admin. All Public API endpoints work, with the same limits.

When a token stops working

Tokens have no fixed expiry. A token works until one of these happens:

Then the API answers 401 {"msg": "Invalid OAuth token"}. Send the user through the flow again.

While the workspace has no active plan, calls answer 401 {"msg": "No subscription found"}. They work again once it has one.

Managing your app

In Settings → Developers → Apps:

Errors

From the token endpoint:

Status Body Meaning
400 {"error": "unsupported_grant_type"} grant_type is not authorization_code
400 {"error": "invalid_grant"} The code is unknown, already used, or belongs to another app
400 {"error": "invalid_grant", "error_description": "Code has expired"} More than 10 minutes since approval
400 {"error": "invalid_grant", "error_description": "code_verifier does not match the code_challenge"} PKCE: missing or wrong code_verifier, or one sent for a code requested without a challenge. The code is not used up.
400 {"message": [...], "error": "Bad Request"} A required field is missing or badly formed
401 {"error": "invalid_client"} Unknown client_id or wrong client_secret
429 More than 30 requests in 5 minutes

On the authorisation page, an unknown client_id, a response_type other than code, or a code_challenge without code_challenge_method=S256 shows an error to the user and does not redirect.