adPluga

Authentication

Authentication

adPluga uses publishable keys on the client and secret keys on the server. Every key is scoped to a property and to an environment — test or live.

Key formats

Publishable keys are safe to embed in HTML or mobile bundles. Secret keys stay server-side and sign server-to-server delivery — audio stitching and email preparation. To manage campaigns, ads and reports from your own system there are integration keys (ak_), with explicit scopes; the dashboard uses your account session.

PrefixUsageScope
pk_test_…clientTest env, safe to embed
pk_live_…clientProduction, safe to embed
sk_test_…serverServer-only. Test env.
sk_live_…serverServer-only. Production.

Test vs live

Test keys never spend budget and never count toward billing. Use them in CI and in staging. Live keys require an active subscription and a verified property.

Integration keys (server-to-server)

For your system to create campaigns and ads without opening the dashboard. Create the key in Settings › Keys, choose what it may do, and send it as a bearer token. The secret is shown once.

curl -X POST https://api.adpluga.com/v1/campaigns \
  -H 'Authorization: Bearer ak_live_•••' \
  -H 'Idempotency-Key: 8f3a…' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Autumn","objective":"traffic","pricing_model":"CPM","bid_cents":200,"pacing":"uniforme"}'

The available scopes are campaign:read, campaign:write, ad:read, ad:write, asset:read, asset:write, property:read and reports:read. Three limits worth knowing before you design the integration:

  • A key only reaches the endpoints its scopes cover. Billing, wallet, payouts, members and key management answer 403 to any key, whatever its scopes.
  • A key acts as the person who created it: if they lose a permission or leave the account, the key loses it too. Issue it from a user with the role the integration should have, not from the account owner.
  • The prefix decides the environment. An ak_test_ key writes in test mode — nothing charged, nothing counted — and is what you develop against; ak_live_ writes for real.

Opening adPluga inside your application

If you do not want your team switching applications to create campaigns, open the adPluga screen inside your own interface. Your server asks for a session with the integration key; the browser opens it in a dialog. Nobody signs in inside the window — the session arrives authenticated.

curl -X POST https://api.adpluga.com/v1/embed/sessions \
  -H 'Authorization: Bearer ak_live_•••' \
  -H 'Content-Type: application/json' \
  -d '{"component":"campaign_create","origin":"https://admin.yourcompany.com"}'

# -> { "client_secret": "cs_•••", "url": "https://api.adpluga.com/embed/campanha/?cs=cs_•••", "expires_at": "…" }
  • The secret is single-use and lasts 5 minutes. Ask for it when the person clicks the button, not on page load.
  • The page only accepts being framed by the origin you named. A different origin is refused by the browser, not by us.
  • What the screen can do is what the key could already do: an ak_test_ key writes in test mode and no header can change that.

Rotating a key

Rotate from the dashboard or via API. The previous key is revoked immediately; rotate before deploying the new one to avoid downtime.

curl -X POST https://api.adpluga.com/v1/sdk-keys/{id}/rotate \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN'

CORS and headers

Send the publishable key as X-AdPluga-Key when calling /v1/serve from the browser. The secret key travels as Authorization: Bearer sk_… on the server-to-server endpoints that accept it. Never expose secret keys client-side.

Storage and rotation

Treat secret keys like passwords. The principle is the same as any sensitive credential: never check them in, never log them, scope every deployment to its own key.

  • Never commit sk_… keys to git. Use .gitignore-protected .env files, GitHub Actions secrets or a secret manager (AWS Secrets Manager, Vault, Doppler).
  • Rotate at least every 90 days and immediately if a key was exposed in logs, build artefacts or a third-party tool.
  • Keep test and live keys in separate accounts and separate environments. A leaked pk_test_ is a non-event; a leaked sk_live_ is a security incident.
  • Keys belong to a property. To isolate an integrator, give them a property and its keys rather than sharing another property's sk_live_.

Tracking tokens (HMAC)

Every /v1/serve response returns a track_token signed with the property's shared secret and a server-side TTL. POST /v1/track payloads must replay that token verbatim — the edge validates the signature, rejects replays beyond the TTL and binds the event to the correct property and slot.

curl -X POST https://edge.adpluga.com/v1/track \
  -H 'Content-Type: application/json' \
  -H 'X-AdPluga-Key: pk_test_•••' \
  -d '{"token":"eyJ…","event":"click"}'

Each token is single-use within the TTL (10 minutes by default). Replaying the same token returns 204 and is not counted twice — retrying is safe.

Error codes

Authentication errors share the standard envelope { error: { code, message } }. The most common codes:

StatusCodeWhen
401missing_keyX-AdPluga-Key header or Authorization bearer is missing.
401invalid_keyKey does not match a known property or is malformed.
403key_revokedKey was rotated or manually revoked from the dashboard.
403tenant_suspendedTenant subscription expired, billing failed or the account was paused.
403wrong_environmentCalling /v1/serve with pk_test_… against the live edge or vice-versa.
429rate_limitedPer-key or per-IP throughput exceeded. Back off using the Retry-After header.

Production checklist

Before flipping the switch to pk_live_… on a real property:

  • Verify the property in the dashboard (DNS or HTML-tag check) — unverified properties cannot serve live traffic.
  • Swap pk_test_… for pk_live_… in your build pipeline, not in source — use environment variables.
  • Monitor /integration/status and /integration/events for the first hour after rollout; the dashboard surfaces both.
  • Watch balance and usage in Billing: a test campaign spends nothing, but a live campaign with an integration bug does.
  • Poll /v1/integration/status and /v1/integration/events from your own system. There are no outbound webhooks — when there are, they will be documented here.