Skip to main content
Every request to the ParlayX API is signed. There are no bearer tokens, no shared secrets in transit, and no way to assert an identity in a request body. Identity comes from the key that signed the request, and from nothing else. A request cannot claim to be an actor it is not, or reach a pod its key was not minted for.

What a key is

An API key is minted for one actor and pod pairing. That pairing is fixed at the moment the key is created and cannot be changed afterward. This has a consequence worth internalizing before you write any code: the key determines scope, so scope never appears in the request. You do not pass a pod ID. You do not pass an actor ID. The API already knows both, because they are properties of the key that signed the call. An actor trading two pods holds two keys and chooses which one to sign with.

Key material

Keys are Ed25519 keypairs generated in your environment. You register the public key with ParlayX; the private key never leaves your systems and we never see it.
The private key is the credential. Anyone holding it can trade the pod it is bound to, up to that pod’s balance. Store it the way you would store a venue API secret — in a secrets manager, never in source control, never in a config file that ships with your application.
If a key is exposed, revoke it. Revocation takes effect at the front door and is reversible. See Actors and permissions.

Signing a request

Every request carries four headers: The sequence:
1

Hash the body

Compute the SHA-256 of the request body and put it in PX-Content-Sha256. For a request with no body, hash the empty string.
2

Build the canonical string

Assemble the canonical string from the request method, path, timestamp, and body hash. The exact composition is given in the API Reference — build it byte for byte, since any deviation produces a signature that will not verify.
3

Sign it

Sign the canonical string with your private key and put the result in PX-Signature.
4

Send

Include all four headers with the request.
The SDK does this for you. Sign manually only if you are working in a language the SDK does not cover.

What gets checked

Two stages, in order. Everything fails closed — an ambiguous result is a rejection, never an approval. At the front door, before your request body is read:
  1. All four headers are present
  2. The timestamp is fresh
  3. The key ID is well formed
  4. The key exists, and its actor and pod are loaded
  5. The signature verifies against the stored public key
  6. The body hash matches what was signed
Signature verification happens before the body is parsed. A request that does not verify is rejected without its contents ever being interpreted. Then the guard, which asks four questions in order: Three separate revocation levers, each independent. You can revoke a single key while leaving the actor intact, revoke the actor across everything it touches, or withdraw the actor’s access to one pod while leaving its other pods working. Pass all four and the request proceeds with a verified identity: organization, pod, actor, and key.

Timestamps

Requests carry a timestamp and are only accepted inside a narrow window, which prevents a captured request from being replayed later. Keep your system clock synchronized. Clock drift on your side presents as authentication failures that look intermittent and are not.

Scope is carried by the key

Because the key pins one actor and one pod, paths on the signed API never name a pod or an organization. There is no /pods/{podId}/orders on the public surface. There is /orders, and it means your orders, in your pod. A signed key can only ever address its own scope. This is structural, not a permission check that could be misconfigured — there is no way to express a request for someone else’s pod, so there is no way to accidentally grant one. Organization-wide and pod-wide oversight lives in the console, which authenticates differently because an administrator legitimately spans many pods.

Confirming what a key is

whoami returns the identity behind the key that called it:
Useful in three situations: verifying your signing implementation before you build anything on top of it, confirming which pod a key is bound to when you hold several, and checking that a key is still live. Today every API key is an actor key with trade capability. The scope and capabilities fields exist so that pod-scoped and organization-scoped read keys can be introduced without changing the response shape. Read them rather than assuming their values.

What an actor key can do

Placing, tracking, and cancelling an order are one responsibility under one grant. There is no configuration in which an actor can cancel an order it cannot see, or see an order it did not place. Capital movement is not an API capability at all. Deposits, withdrawals, and rebalancing are administrative actions. See Deposit and Rebalance.

Rotation

Rotating issues a new key and retires the old one — same actor, same pod, same access, new credential. Rotate on a schedule, when someone with access to the key leaves, and immediately if exposure is suspected. Nothing about the actor, its pod, or its open positions is affected.

Authentication failures

Signature failures are almost always the canonical string or the body hash. Call whoami first — it is the smallest signed request you can make, and if it succeeds your signing is correct and the problem is in how you built that specific request.