Skip to main content
Socialift
Documentation sections
Authentication

Authentication: license keys, seats and platform tokens

The Socialift SDK runs on an slk_... license key. The key is signed with Ed25519 and checked offline first; then, before the first request, the SDK obtains a 12-hour lease from the license server. If the server is unreachable, the SDK keeps working for 7 days after the last successful confirmation. Each environment takes one seat — set SOCIALIFT_INSTANCE_ID in containers.

Updated:

Which keys are involved when you use Socialift?

There are three kinds of keys and they must not be confused. The license key (slk_...) is your right to use the Socialift SDK; it is never sent to the platforms. Developer app keys (Meta App ID and secret, LinkedIn and TikTok client credentials, Telegram api_id/api_hash) identify your app to a platform. Platform tokens (OAuth access tokens, Page tokens, bot tokens, Telegram sessions) authorize actions on behalf of a specific user or account.

License key vs developer app key vs platform token

License key vs developer app key vs platform token — Capability matrix by platform
License keyDeveloper app keyPlatform token
Exampleslk_...Meta App ID + App Secret; LinkedIn Client ID/Secret; TikTok Client Key/Secret; Telegram api_id/api_hashUser or Page access token, TikTok refresh token, bot token, Telegram session
Issued bySocialift dashboard → “Tokenlar” (Tokens)The platform's developer consoleOAuth, @BotFather or phone login
PurposeAllows the SDK to runIdentifies your app: OAuth, signaturesCalls on behalf of a specific account
How the SDK gets itSOCIALIFT_LICENSE_KEY or license_key=Constructor: Facebook(app_id=..., app_secret=...) or from_env()An argument of each method: fb.pages(token)
Where to keep itServer environment variable or secret managerServer environment variable or secret managerYour database, encrypted
Notes and limits

The dashboard sections “Kalitlar” (Keys) and “Ulanishlar” (Connections) serve the Playground and the Socialift server. The SDK in your own app is not linked to them — you pass keys and tokens yourself.

How do you pass the license key to the SDK?

There are three ways. Precedence: the license_key= argument → SOCIALIFT_LICENSE_KEY → set_license_key().

license_key.py
import os
import socialift
from socialift import Facebook

# 1) Environment variable (recommended): SOCIALIFT_LICENSE_KEY=slk_...
fb = Facebook.from_env()

# 2) Explicit argument — wins over the environment variable
fb = Facebook.from_env(license_key=os.environ["BILLING_SLK"])

# 3) Process-wide (notebooks, tests)
socialift.set_license_key("slk_...")

Note: when SOCIALIFT_LICENSE_KEY is set, it takes precedence over set_license_key(). If a notebook seems to “ignore” a new key, check the environment variable first.

The key is checked before the first request, not when the client is created. All clients using the same key in one process share a single activation. TelegramAccount accepts license_key= as well.

The webhook helpers (socialift.webhooks) and socialift.crypto functions make no network calls and do not check the license.

How is the license checked?

  1. Offline: format and signature

    The key looks like slk_<payload>.<signature>. The SDK checks the prefix, the format and the Ed25519 signature against the embedded public key, plus the expiry written into the key. If the format or signature is wrong, it raises LicenseInvalid immediately, without any network call. If the expiry in the key has passed, SDK 1.3+ first asks the server for the current expiry (the token may have been renewed), while offline mode and SDK 1.2.x raise LicenseExpired right away.

  2. Online: obtaining a lease

    Before the first request the SDK sends the key, an environment fingerprint (a hash) and the SDK and Python versions to the license server and receives a lease. The default is 12 hours and the server sets it. While the lease is valid, the SDK does not contact the server again.

  3. Automatic renewal

    When the lease expires, it is renewed before the next request. If the server changed the plan or features, the new state applies without issuing a new key. When a token is renewed, the dashboard shows a re-signed key with the same key_id: SDK 1.3+ picks up the new expiry from the server automatically, while with the 1.2.x release on PyPI or SOCIALIFT_LICENSE_OFFLINE=1 you replace SOCIALIFT_LICENSE_KEY with that key.

  4. Offline grace period

    If the server is unreachable or returns any error other than 403, and the last successful confirmation is less than 7 days old, the SDK keeps working and re-checks the server every hour. After 7 days, or with no confirmation on record, it raises LicenseError.

  5. Revocation is immediate

    If the server returns 403 (key revoked, seat limit reached or environment blocked), grace does not apply: LicenseRevoked is raised at once and the cached confirmation is deleted.

License environment variables

License environment variables — Capability matrix by platform
VariableDefaultPurpose
SOCIALIFT_LICENSE_KEYnoThe slk_... license key
SOCIALIFT_INSTANCE_IDhash of hostname, architecture and MAC addressStable environment name — seats are counted by it
SOCIALIFT_LICENSE_OFFLINEoff1, true or yes — offline signature check only, no server calls
SOCIALIFT_LICENSE_ENDPOINThttps://api.socialift.uz/api/v1/licenseLicense server URL; do not change unless Socialift tells you to
XDG_CACHE_HOME~/.cacheWhere socialift/license.json (last confirmation time) is written — the grace period depends on it

yesno

If outbound traffic is restricted (firewall, egress rules), allow HTTPS to api.socialift.uz.

How does the offline grace period work?

Grace is measured from the last successful activation, not from the moment the server stopped answering. The SDK records that time in ~/.cache/socialift/license.json (or $XDG_CACHE_HOME/socialift/license.json). If the server is unreachable and fewer than 7 days have passed since then, the SDK logs a warning and keeps working.

Recreating a container wipes that file. If a fresh container starts while the server is unreachable, there is no record to grant grace and the first request fails with LicenseError. To keep grace across deploys, mount the cache directory on a persistent volume or point XDG_CACHE_HOME at one.

403 responses — a revoked key, the seat limit, a blocked environment — never enter grace.

When should you use SOCIALIFT_LICENSE_OFFLINE?

For environments with no outbound network access, such as an isolated CI or an air-gapped network. In this mode only the key signature and the expiry inside the key are checked; the license server is never contacted.

Consequences: server-side revocation has no effect, plan changes do not arrive, and the signed rules bundle delivered with the lease (Graph field sets, the lead field mapping table) is not refreshed, so the SDK works with a cached or a minimal baseline set. The mode is not recommended for regular production.

What is a seat, and why do Docker and Kubernetes need SOCIALIFT_INSTANCE_ID?

A seat is one environment in which the key may run at the same time. An environment is identified by a fingerprint: the SHA-256 of SOCIALIFT_INSTANCE_ID when set, otherwise a hash of hostname, architecture and MAC address. Docker gives every new container a new hostname and MAC, so each deploy takes a new seat, and once the limit is reached the SDK stops with LicenseRevoked (the message says “Seat chegarasi”, the seat limit).

A fingerprint that is already registered does not take a new seat when it activates again. Occupied seats are not released automatically: you can see them under “Tokenlar” (Tokens) → “Tekshirish va muhitlar” (Check and environments); contact support to free them.

Give each environment one stable name, for example my-app-prod and my-app-staging.

Naming the environment in Kubernetes and Docker

deployment.yaml
# Kubernetes Deployment (excerpt)
env:
  - name: SOCIALIFT_INSTANCE_ID
    value: my-app-prod
  - name: SOCIALIFT_LICENSE_KEY
    valueFrom:
      secretKeyRef:
        name: socialift
        key: license-key

# Docker:
# docker run -e SOCIALIFT_INSTANCE_ID=my-app-prod -e SOCIALIFT_LICENSE_KEY my-app:latest

Checking the license at startup

Catch problems at deploy time instead of on a user's first request.

startup.py
import asyncio
from socialift import LicenseError, LicenseManager


async def check_license():
    try:
        lic = await LicenseManager.get().ensure()
    except LicenseError as exc:
        raise SystemExit(f"Socialift license is not usable: {exc}")
    print(lic.key_id, lic.plan.value, lic.expires_at, lic.seats)


asyncio.run(check_license())

LicenseManager.get() resolves the key exactly like the clients do and returns the manager they share: called inside your app, later requests do not activate again. A separate process on the same machine arrives with the same fingerprint and takes no new seat.

lic.features is the set of features open on your plan.

License errors and how to fix them

License errors and how to fix them — Capability matrix by platform
ErrorWhen it is raisedWhat to do
LicenseErrorBase class. The server did not confirm and no grace applies: network error, server failure, or a rejected key outside the grace periodCheck the network and the key — the reason is in the message
LicenseRequiredNo key found: license_key=, SOCIALIFT_LICENSE_KEY and set_license_key() are all emptySet the environment variable
LicenseInvalidPrefix is not slk_, the format is broken, the signature does not match, or cryptography is missingCopy the whole key again, without spaces
LicenseExpiredThe token has expired (on SDK 1.2.x and in offline mode, the date written into the key)Renew the token under “Tokenlar” (Tokens); on SDK 1.2.x or in offline mode also switch to the re-signed key
LicenseRevokedThe server returned 403: key revoked, seat limit reached or environment blockedRead the message; for seats, set a stable SOCIALIFT_INSTANCE_ID
FeatureNotInPlanThe method needs a feature outside your plan; has feature and plan attributesUpgrade the plan

All of them inherit from LicenseError → SocialiftError, not from ApiError, so they never mix with platform errors.

Does checking a key in the dashboard use a seat?

No. The “Tekshirish va muhitlar” (Check and environments) button on the “Tokenlar” (Tokens) page, like “Tekshirish” (Check) in “Qo'llanma” (Guide), does not call the SDK activation; it only reads the stored state. Press it as often as you like.

It shows whether the key works with the SDK (and why not, if it doesn't), the plan, seats in use (for example 1 / 1), the lease length in hours, the last activation time, open features and the “Muhitlar” (Environments) table: fingerprint prefix, SDK and Python versions, first and last seen, activation count. When every seat is taken, the page warns about it explicitly.

Rotating or revoking a key

  1. Get a new key

    “Tokenlar” (Tokens) → “Yangi token” (New token). It is a separate token with its own term and seat. An account can hold up to 5 active tokens at a time.

  2. Replace it in every environment

    Update SOCIALIFT_LICENSE_KEY in your secret manager or environment; keep SOCIALIFT_INSTANCE_ID unchanged.

  3. Restart the processes

    The SDK caches the key inside the process, so the new key is used after a restart.

  4. Have the old or leaked key revoked

    The dashboard has no revoke button for users — email the key's key_id to hello@socialift.uz. Revocation takes effect at the next lease renewal (within 12 hours), and the SDK then stops with LicenseRevoked.

Frequently asked questions

Is the license key checked on every API request?

No. The SDK contacts the license server at startup and whenever the lease expires (12 hours by default). SDK calls to Instagram, TikTok and the other platforms never pass through the Socialift server.

Will production stop if the license server is down?

Not within 7 days of the last successful confirmation: the SDK runs in offline grace mode and re-checks the server every hour. This requires the cache file holding that confirmation (~/.cache/socialift/license.json) to survive — mount it on a persistent volume in containers.

How many servers can use one key?

As many environments as the key has seats. A new token from the dashboard comes with 1 seat, and “Tekshirish va muhitlar” (Check and environments) shows how many are in use. Contact Socialift if you need more seats.

What is the difference between the license key and a Meta App Secret?

The license key is your right to use the SDK and is sent only to the Socialift license server. The App Secret belongs to your Meta app: it is used for the OAuth code exchange, appsecret_proof and webhook signatures. Neither replaces the other, and both stay on the server.

I called set_license_key() but a different key is used. Why?

Precedence is the license_key= argument first, then SOCIALIFT_LICENSE_KEY, and set_license_key() last. If the environment variable is set, it wins over set_license_key() — unset it or pass the key as an argument.

Every Docker deploy ends with a “Seat chegarasi” (seat limit) error. What should I do?

Set a stable SOCIALIFT_INSTANCE_ID (for example my-app-prod) so later deploys stay on one seat. Seats taken by earlier deploys are not released automatically: review them under “Tekshirish va muhitlar” and contact support to free them.

Related pages