oqimDocs
API referenceConsole

Start here

  • Introduction
  • Getting started

Guides

  • Telegram accounts
  • Recipients
  • Campaigns
  • Scheduling
  • Webhooks
  • AI writing assistant

AI Seller

  • AI Seller
  • Channels
  • Live inbox
  • Past conversations and privacy
  • Business insights

API

  • Authentication
  • API reference
  • SDK
  • Errors
  • Rate limits

Trust and operations

  • Security
  • Compliance
  • Administration
Docs / Authentication

Start here

  • Introduction
  • Getting started

Guides

  • Telegram accounts
  • Recipients
  • Campaigns
  • Scheduling
  • Webhooks
  • AI writing assistant

AI Seller

  • AI Seller
  • Channels
  • Live inbox
  • Past conversations and privacy
  • Business insights

API

  • Authentication
  • API reference
  • SDK
  • Errors
  • Rate limits

Trust and operations

  • Security
  • Compliance
  • Administration

Authentication

People use the console with a session cookie. Programs use API keys, either directly or exchanged for a one-hour access token. Every request acts in one organization and is checked against a role.

Console sessions#

Signing in with POST /api/v1/auth/login sets the oqim_session cookie: HTTP-only, SameSite=Lax, Secure in production, and valid for 14 days by default (SESSION_TTL_HOURS). The browser sends it with every request to your Oqim host; your code never handles it. The server keeps only a SHA-256 hash of the session token.

  • A session belongs to one user and has one active organization. Switch with POST /me/switch-organization.
  • If the user has two-factor authentication on, sign-in answers {"mfa_required": true}. Until a code is posted to POST /auth/mfa/verify, the session can only call that endpoint, GET /me and POST /auth/logout; everything else returns 401 mfa_required.
  • Requests that change data with a cookie must come from an allowed origin (ALLOWED_ORIGINS), or they fail with 403 origin_rejected. Requests with a bearer credential are exempt, because browsers never attach one on their own.
  • Disabling a user ends their sessions immediately.

Scripts and integrations should use API keys rather than console sessions.

API keys#

Owners and Admins create keys in the console under API & webhooks, or with POST /api-keys. A key looks like this:

API key
oqk_n4v8t2kq7wzc_yR3fT9qLm2Vx8KpZc6WnB4sHd1JgQ7eU0aXoN5tYiEw

It's oqk_, a 12-character prefix Oqim uses to find the key, an underscore, and the secret. The full key is shown once, when it's created; Oqim stores only its SHA-256 hash, and the console shows the prefix so you can tell keys apart. Send it as a bearer token:

Shell
curl https://app.example.com/api/v1/campaigns \
  -H "Authorization: Bearer $OQIM_API_KEY"
  • A key belongs to one organization and acts with the API_CLIENT role (see below). It can't use the console, switch organizations or call the administration API.
  • Keys can expire: pass expires_in_days when creating one. Oqim records when and from which IP each key was last used.
  • Keep keys on servers. Anyone holding a key can act as your organization within its permissions.

Access tokens#

If you'd rather not send the long-lived key on every request, for example from a job runner that logs request headers, exchange it for an access token that lasts one hour:

Shell
curl https://app.example.com/api/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{"grant_type": "api_key", "api_key": "'"$OQIM_API_KEY"'"}'
Response · 200 OK
{
  "access_token": "oqat_eyJrIjoia2V5XzAxajlyOGExYzNlNWc3ajltMXAzcjV0N3c5IiwibyI6Im9yZ18wMWo5cjJtNmsi.Hq2vX8bN3mK5pL7rT9wY1zA4cE6gJ0sU",
  "token_type": "Bearer",
  "expires_in": 3600,
  "expires_at": "2026-09-26T10:30:00Z"
}
  • Send access_token as Authorization: Bearer oqat_…, exactly like a key. It has the same permissions as the key it came from.
  • Tokens can't be refreshed. Request a new one before expires_at.
  • Every request re-checks the key behind a token, so revoking the key invalidates its tokens at once.
  • /auth/token is a public endpoint limited to 30 requests per minute per IP. Reuse a token for its whole hour instead of requesting one per call.

Rotating and revoking keys#

Rotate a key in the console or with POST /api-keys/{id}/rotate. The response contains the new key, shown once. The old key keeps working for 24 hours so you can deploy the new one, then stops. The new key's rotated_from names the key it replaced.

If a key may have leaked, revoke it with DELETE /api-keys/{id} instead. Revocation is immediate and also ends every access token issued from that key.

Roles and permissions#

Every membership has one role, and every API key has API_CLIENT. The API checks permissions, never role names; each endpoint in the API reference lists the permission it needs.

PermissionAllowsOwnerAdminManagerOperatorViewerAPI key
org:readSee the organization, notifications
org:manageRename, change time zone, accept the policy––––
members:readSee the team and invitations–
members:manageInvite, change roles, remove members––––
accounts:readSee Telegram accounts
accounts:manageConnect, pace, pause and remove accounts––––
proxies:readSee proxies
proxies:manageAdd, change and remove proxies––––
recipients:readSee recipients, lists and suppressions
recipients:manageImport, edit, opt out, suppress––
campaigns:readSee campaigns, templates, jobs, events
campaigns:manageCreate and edit campaigns and templates––
campaigns:executeLaunch, pause, resume, cancel–
analytics:readDashboard and analytics
audit:readRead the audit log––––
developers:manageCreate, rotate and revoke API keys––––
webhooks:readSee webhooks and deliveries–
webhooks:manageAdd, change, test and delete webhooks–––
billing:readSee plan limits and usage––––
  • A request without the needed permission fails with 403 forbidden, and the message names the missing permission.
  • While an organization is suspended, every *:manage permission and campaigns:execute are refused with 403 organization_suspended. Reading still works.
  • Only Owners can make someone an Owner or remove one; Admins manage every other role.
  • API keys can import recipients and run campaigns, but connecting Telegram accounts, managing the team and managing keys always take a person in the console.

Two-factor authentication#

Anyone can turn on TOTP two-factor authentication under Settings → Profile & security. Under the hood:

Enroll

POST /me/mfa/setup returns a secret and an otpauth:// URL to show as a QR code. Nothing changes until POST /me/mfa/enable confirms a first code. Codes have 6 digits, change every 30 seconds, and one step of clock drift is accepted. The secret is stored encrypted.

Platform administrators

The admin console refuses administrators without two-factor authentication (mfa_enrollment_required) and asks for a code in every new session. See Administration.

Note

Authenticator apps compare codes against their device clock. If codes are rejected, check that the phone's time is set automatically.
PreviousBusiness insightsNext API reference