Authentication

Every request to /v1/* requires an Authorization: Bearer header. The token is your public key and secret, joined by a single colon.

Authorization: Bearer gspk_live_<32 hex>:gssk_live_<48 hex>

The dashboard returns the pre-built bearer_token field at credential creation time so you can drop it in directly.

How a request actually flows

You make ONE call. We handle the rest:

Your server                    GhostSwap                     Liquidity layer
                                                            (cryptographic
                                                             signing handled
                                                             entirely by us)
    │
    │ GET /v1/currencies
    │ Authorization: Bearer <pk>:<sk>
    ├──────────────────────────►│
    │                           │ 1. Look up credential by gspk_live_*
    │                           │ 2. argon2-verify gssk_live_* against hash
    │                           │ 3. Build internal request
    │                           │ 4. Sign with our keypair
    │                           ├──────────────────────────►│
    │                           │                           │ Verify signature,
    │                           │                           │ fetch currencies
    │                           │◄──────────────────────────┤
    │                           │ 5. Translate to our shape
    │ 200 { currencies: [...] } │
    │◄──────────────────────────┤
    │

You never touch upstream signing keys. You never sign anything. You just send Bearer-authenticated HTTPS — exactly like Stripe, Twilio, OpenAI, etc.

Key shapes

FieldFormatVisibility
Public keygspk_live_<32 hex>Safe to log. Identifies the credential at request-time. Always visible on the credentials list.
Secretgssk_live_<48 hex>Stored as both an argon2id hash (for auth) and AES-256-GCM encrypted (for recovery). Re-viewable from your dashboard via Reveal secret.

Issuing credentials

In the dashboard at /dashboard/api-credentials:

  1. Your organization must be in active status (an admin approves your application first).
  2. Click Create live credential, give it a descriptive name (Production, Staging, etc.), and click Create.
  3. The dashboard returns three values: your public key, your secret, and a pre-built bearer token (<public_key>:<secret>).
  4. Treat the secret like any production secret — store in a secret manager or env var, never in source control or browser bundles.

The credential is owned by your organization, not your individual user account. Any team member of the org can manage credentials.

Recovering a lost secret

If you lose track of your secret:

  1. Visit /dashboard/api-credentials
  2. Find the credential row → click Reveal secret
  3. The secret + a fresh bearer token are shown again, with a Hide button to collapse

Every reveal is audit-logged on our side. If a credential's secret was created before this feature shipped (early-stage credentials), Reveal returns a friendly message explaining that recovery isn't available — revoke + reissue to upgrade to a recoverable credential.

If you suspect a secret has leaked, revoke it instead of revealing — that invalidates it across all environments and gives you a fresh credential.

Rotating

In v1 your account holds one active credential at a time. The dashboard hides the "Issue credential" form while an active key exists, so rotation is a deliberate two-step:

  1. Plan a maintenance window. Between revoke and issue, API calls return HTTP 401. Pick a low-traffic time, or coordinate with us at support@ghostswap.io if you need a hot-cutover.
  2. Revoke the active credential. From /dashboard/api-credentials, hit Revoke on the row. Revocation is immediate — the next request using the old credential returns 401 unauthenticated.
  3. Issue a fresh credential in the same dashboard. The form re-appears once the old one is revoked.
  4. Roll the new bearer token into your environment and confirm traffic by watching the Last used timestamp on the new row.

Revoked credentials cannot be re-activated. We keep them in your history (greyed out) so you can audit which credential signed each swap.

If you suspect a secret has leaked, revoke immediately — don't worry about the maintenance window. A short period of 401s is much better than a leaked active credential.

Where to put the token

Server-side environment variables. Loaded into your runtime via your hosting provider's secret manager.

Backend service-to-service traffic with the bearer in the Authorization header.

Never in URL query strings — they leak into server logs and browser referrer headers.

Never in browser-side code, single-page apps, or mobile apps. Anything served to a client device is recoverable. Proxy through your own backend.

Never in source control, even private repos. Use a .env file that's gitignored, or a secret manager.

Security checklist

  • Credentials live in env vars or a secret manager, not in code.
  • You have a tested rotation runbook.
  • You alert on unexpected 401 responses (could indicate a revoked or rotated credential).
  • Your egress traffic is over HTTPS only (TLS 1.2+).
  • You log the response X-Request-Id header — useful when escalating to GhostSwap support.

What's coming

The roadmap covers planned credential-management features:

  • Test-mode keys (gssk_test_*) so you can develop without spending real funds.
  • Per-credential IP allowlists.
  • Per-credential method scopes (e.g. read-only credentials).
  • Last-used IP and user-agent in the dashboard.