Authentication
Every authenticated request carries a bearer token:
Authorization: Bearer <your-token>The same token authenticates the REST API, the MCP server and the CLI.
Create a token in Postlyra
- Open app.postlyra.com and sign in.
- Go to your profile, then the API tokens tab (
/profile/api-tokens). - Click Create token, give it a name you will recognise later, and confirm with your password.
- Copy the token immediately.
The token is shown once. Postlyra stores a hash of it, not the token, so it genuinely cannot be shown again. If you lose it, revoke it and create another.
A token from here is full account access
There are no per-brand tokens: a token can read and write everything its owner can, across every brand on the account. Store it like a password, never commit it, and revoke it the moment a machine holding it is lost.
Tokens do not expire. The only way one stops working is if you revoke it on that page, or POST /auth/logout with it.
A narrower token, for one brand's integrations
Studio, then Settings, then the API tab (owner only) mints a different kind of token: reaches every brand you belong to the same way, but limited to one access tier you pick at creation.
| Tier | Can do |
|---|---|
read | List and read posts, channels, media |
standard_write | Everything above, plus create drafts and submit them for review |
elevated_write | Everything above, plus approve: true when creating a post through Posts, audited in your name |
A token's tier is fixed at mint time. Calling something above it is refused with 403 and a tier_denied code. This is the same tier system an MCP connection's consent screen uses, so the two stay consistent.
Get a token from the CLI
postlyra login gets its own token without any of this: it opens this page's flow in your browser, you approve once, and the token lands in the CLI's config. See the CLI.
Get a token programmatically
A client with no browser at all can trade credentials for a token directly, the same call postlyra login --with-password makes.
curl -X POST https://api.postlyra.com/auth/login \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"email":"ada@example.com","password":"..."}'{
"user": { "id": 1, "email": "ada@example.com" },
"teams": [{ "id": 1, "name": "My Brand", "slug": "0f8fad5b-..." }],
"current_team": { "id": 1 },
"token": "1|AbCdEf..."
}With two-factor enabled
The login response is a challenge instead of a token:
{ "two_factor_required": true, "two_factor_token": "9f2c..." }Exchange it within 300 seconds:
curl -X POST https://api.postlyra.com/auth/two-factor-challenge \
-H "Content-Type: application/json" \
-d '{"two_factor_token":"9f2c...","code":"123456"}'Send recovery_code instead of code to use a recovery code.
Both endpoints are throttled to 10 requests per minute.
Revoking
| How | Effect |
|---|---|
| Profile, then API tokens, then Revoke | Deletes that one token |
POST /auth/logout | Deletes only the token used to make that call |
| Deleting your account | Deletes every token on it |
You cannot revoke the token you are currently signed in with from the token page. Do it from another session.
Passkeys
Passkey login is available for the app. It is a WebAuthn ceremony over POST /auth/passkeys/login/options then POST /auth/passkeys/login, and it returns the same payload as password login. It needs a browser to perform the ceremony, so it is not a practical way to authenticate a script. Use a token from the profile page instead.