API authentication

Every Storlaunch API request must include an API key. We use a plain Authorization: Bearer scheme — no request signing, no timestamping, no idempotency-key hashing. The key itself is the credential.

This page covers the exact recipe and the security model. If you're using one of our SDKs (Node, Python, Go), the key is set once at client construction and added to every request automatically.

TL;DR

For every request:

  1. Mint an API key in the dashboard.
  2. Send it as Authorization: Bearer <key> on every request.
  3. That's it.
curl https://storlaunch.forjio.com/api/v1/storefront/products \
  -H "Authorization: Bearer sk_test_xxxxxxxxxxxxxxxxxxxxxxxx"

The key types

Storlaunch issues two kinds of keys, each in two environments:

Prefix Environment Access Used for
pk_test_… Test Read-only public data (products, storefront) Frontend code in development
pk_live_… Live Read-only public data (products, storefront) Frontend code in production
sk_test_… Test Full account access Backend integration in development
sk_live_… Live Full account access Backend integration in production

Publishable keys (pk_*) are safe to embed in client-side JavaScript — they only allow reads on public data (your storefront's product catalog). Storlaunch's auto-generated storefronts use them.

Secret keys (sk_*) grant full read/write on the workspace. Server-only. Anyone with one can place orders, refund payments, change settings.

Generate one

In the dashboard, navigate to Settings → API keys (or /dashboard/api-keys).

Click Create API key:

  1. Pick a name (e.g., "Production webhook handler").
  2. Pick an environment: Test or Live.
  3. Pick an access level: Publishable (read-only public) or Secret (full access).

Storlaunch shows the key value once. Copy it into your environment manager immediately.

The key appears only once. When you create a key, Storlaunch shows it in a dialog. If you close it without copying, you have to mint a new key. There's no recovery flow.

Sending the header

Every authenticated request has one header:

Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx

If you're sending a body (POST/PUT/PATCH), also send Content-Type: application/json.

Optional headers worth knowing:

Header Purpose
X-Account-Id Override which workspace this request operates on (for users who are members of multiple). Defaults to the key's home workspace.
Idempotency-Key Make a mutation safely retryable. Same key within 24h returns the same response.
User-Agent We log this; it helps us debug. Use something descriptive like my-app/1.0.

A complete curl example

export STORLAUNCH_API_KEY=sk_test_xxxxxxxxxxxxxxxxxxxxxxxx

# List products
curl https://storlaunch.forjio.com/api/v1/storefront/products?limit=5 \
  -H "Authorization: Bearer $STORLAUNCH_API_KEY"

# Create a product
curl -X POST https://storlaunch.forjio.com/api/v1/storefront/products \
  -H "Authorization: Bearer $STORLAUNCH_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: product-import-2026-05-12-001" \
  -d '{
    "name": "Concert ticket",
    "price": 250000,
    "currency": "IDR",
    "type": "digital"
  }'

Why not HMAC?

Plugipay (also in the Forjio family) uses HMAC-SHA256 request signing because payment APIs sign every individual request to defend against replay and tampering — the upside is large because the operations are financially sensitive.

Storlaunch's surface is e-commerce operations: products, orders, fulfilment. The replay risk is lower (you can't double-place an order easily, and idempotency keys handle the legitimate retry case), the integration surface is broader, and the value of "easier to integrate" is higher.

So we picked bearer tokens for Storlaunch and accept the trade-off. Treat your secret key like a password — transport-encrypted (HTTPS), stored in a secret manager, rotated periodically.

Storlaunch as a Plugipay partner

Under the hood, Storlaunch is a Plugipay partner — every time your storefront takes a payment, Storlaunch calls Plugipay's API on behalf of your workspace's auto-provisioned Plugipay account.

You don't see this; it's an internal detail. But it does mean:

  • You don't need a separate Plugipay API key to operate your Storlaunch store. The Storlaunch key is sufficient.
  • The Plugipay-backed routes (/api/v1/payment/*) accept your Storlaunch key — Storlaunch translates them into Plugipay calls with the appropriate X-Plugipay-On-Behalf-Of header.
  • Plugipay webhooks flow to Storlaunch first (/api/v1/webhooks/plugipay); Storlaunch normalizes them and re-emits Storlaunch-shaped events to your webhook endpoints.

If you want to call Plugipay directly — for an advanced flow not exposed via Storlaunch — you can mint a Plugipay key in the Plugipay dashboard under your auto-provisioned Plugipay workspace.

Multi-workspace keys

A key is scoped to the workspace it was created in. To call the API for a different workspace, mint a key in that workspace.

If you're a platform admin operating many merchant workspaces, you'll have one key per workspace. Storlaunch doesn't currently expose a "platform-level" key that can scope per-request via a header — this is a feature on the roadmap, not shipped.

Security model

A few rules to live by:

  • Treat sk_* keys like passwords. Anyone with one can take any action on the workspace.
  • Never embed sk_* in frontend code. Use pk_* for client-side reads of public data. Storlaunch enforces this server-side — a pk_* key sent against a write endpoint returns 403 INSUFFICIENT_PERMISSIONS.
  • Don't log keys. Truncate to last-4 in any logs you keep.
  • Rotate periodically. From Settings → API keys, click an existing key and Rotate. The old value continues to work for a 24-hour grace period; we email the workspace owner.
  • Revoke immediately if compromised. Revoking is instantaneous — no grace.

Webhook signatures vs API keys

This page covers outbound API requests (your code → Storlaunch). Storlaunch also signs inbound webhooks (Storlaunch → your endpoint) with a separate HMAC-SHA256 scheme using the X-Storlaunch-Signature header.

Webhook signing keys are minted per webhook endpoint, not per API key, and are independent. See API → Webhooks (coming soon) for the verification recipe.

Common errors

401 AUTHENTICATION_REQUIRED

No Authorization header was present, or it didn't start with Bearer . Check that:

  • The header is exactly Authorization: Bearer <key> (case-sensitive on Bearer).
  • The key isn't empty.
  • There's no extra whitespace on either side.

401 INVALID_API_KEY

The key is malformed, was revoked, or doesn't exist. Verify:

  • It matches one in Settings → API keys.
  • It hasn't been revoked (revoked keys show a strikethrough in the UI).
  • You're not mixing test and live keys with the wrong environment.

403 INSUFFICIENT_PERMISSIONS

The key is valid but doesn't have access to this operation. Most common cause: using a pk_* (publishable) key on a write endpoint. Use an sk_* key.

429 RATE_LIMITED

You exceeded the per-workspace rate limit. Check the Retry-After header and back off.

Next

  • API overview — the envelope, pagination, idempotency.
  • SDKs — if you'd rather not write the HTTP yourself.
  • Authentication overview — the browser-side OIDC flow (different model, different audience).