Authentication
Public vs. private access, scoped API keys, canonical request signing, and EIP-712 account/order authorization.
Draft v0.1 — design contract, not yet a live service
This documentation set defines a proposed Time Seventeen protocol for review and implementation planning. https://api.t17.capital is the approved and reserved REST origin, but neither that origin nor any documented endpoint is claimed to be live. The WebSocket origin remains unspecified. Credentials, chain IDs, contract addresses, rate limits, and SLAs remain unapproved; IDs, prices, and timestamps shown throughout are illustrative, not real production data.
Time Seventeen authentication is layered. Each layer answers a different question, and a request may need to satisfy several of them at once.
Trust layers
- Public market/index/reference reads — no identity requirement unless operational policy later configures one. Covers index, market, price, rating, and severity discovery/history endpoints.
- API credential request authentication — key ID + canonical request signature + timestamp + nonce, required for all private account/trading endpoints.
- Wallet/account binding — an EIP-712
T17ApiAuthorizationproving control of a signer and delegating defined scopes to an API credential. - Order authorization — every order is independently EIP-712 signed as a
T17Order, even when the surrounding HTTP request is already API-authenticated.
API keys
API keys have explicit environments (for example sandbox, production — both remain production configuration placeholders in Draft v0.1) and explicit scopes:
| Scope | Grants |
|---|---|
market_data:read | Public index/market/price/rating/severity reads (redundant with anonymous access but usable for higher-tier limits) |
account:read | Balances, positions, settlement reads |
orders:read | Order/fill list and detail reads |
orders:write | Order create/amend/cancel/batch/cancel-all |
settlement:read | Settlement/redemption reads |
Key lifecycle — creation, listing, rotation, revocation, and audit logging — is documented as a contract, not as a claim that a live self-service endpoint exists yet:
POST /account/api-keys create a scoped key for an environment
GET /account/api-keys list keys (never returns the secret again)
POST /account/api-keys/{key_id}/rotate
POST /account/api-keys/{key_id}/revoke
GET /account/api-keys/{key_id}/audit-logKeys MAY be restricted to an IP/network allowlist where an account’s operational policy requires it. A key’s secret is shown exactly once at creation time and must be stored in an approved secret manager — never in source control, logs, or client-side JavaScript.
Canonical request signing
Every private REST request carries these headers:
T17-Access-Key: <key-id>
T17-Access-Timestamp: <unix-ms>
T17-Access-Nonce: <unique-nonce>
T17-Access-Signature: <encoded-signature>
T17-Access-Signature-Version: v1The signed canonical request is built from: HTTP method, normalized path, canonically sorted query string, a SHA-256 hash of the request body, the timestamp, the nonce, the key ID, and the environment/audience. The server rejects replay of a previously accepted (key_id, nonce) pair. Exact clock-skew tolerance and nonce-retention window are production configuration, not fixed by Draft v0.1.
T17-Access-Signature-Version=v1
method=POST
path=/v1/orders
query=
body_sha256=<sha256-hex-of-request-body>
timestamp=1788350400000
nonce=n_demo_9f21c3
key_id=key_demo_001
environment=sandbox{
"outcome_id": "out_demo_001",
"side": "BUY",
"price": "0.6400",
"quantity": "150.00",
"time_in_force": "GTC"
}EIP-712 account authorization
T17ApiAuthorization is a wallet-signed typed-data message that binds an owner and signer to an account and delegates scopes to a specific API key:
| Field | Purpose |
|---|---|
owner | The account-controlling address |
signer | The address authorized to sign on the owner’s behalf (may equal owner) |
account | The Time Seventeen account this authorization applies to |
api_key_id | The API key this authorization is bound to |
scopes_hash | Hash of the granted scope set |
environment | The environment this authorization is valid in |
issued_at / expiry | Validity window |
nonce | Authorization-specific replay protection |
authorization_version | Schema version of this typed-data message |
Domain separation includes the protocol name, major version, chain ID when applicable, a verifying contract when one is deployed, or a production-approved salt/audience when verification happens off-chain.
{
"name": "TimeSeventeen",
"version": "1",
"chainId": "YOUR_APPROVED_CHAIN_ID",
"verifyingContract": "YOUR_APPROVED_VERIFYING_CONTRACT",
"salt": "YOUR_APPROVED_DOMAIN_SALT"
}EIP-712 order authorization
Every order is independently signed as a T17Order typed-data message, regardless of the request-level API signature:
| Field | Purpose |
|---|---|
account | Funding/settlement account for the order |
signer | Address that produced this signature |
market / outcome | The instrument and side being ordered |
side | BUY or SELL |
limit_price (integer + scale) | Fixed-point limit price, encoded as an integer plus a scale to keep the signed payload unambiguous |
quantity (integer + scale) | Fixed-point order quantity |
time_in_force | GTC, GTD, FOK, or FAK |
expiry | Required when time_in_force is GTD |
client_order_id_hash | Hash of the client-supplied order ID |
nonce | Order-specific replay protection |
fee_cap / risk_cap | Signed economic bounds the server MUST honor |
settlement_asset | The asset the order settles in |
signature_version | Schema version of this typed-data message |
The transport body MAY add non-authorizing metadata (for example a client tag), but any field that can change the order’s economic effect MUST be part of the signed payload.
Signer and funder are never assumed equal
The signer that produces a signature and the account/funder that settlement debits or credits are never silently assumed to be the same address. Both are explicit, separately validated fields.
EOA vs. smart-account signatures
EOA (externally owned account) and smart-account/ERC-1271-style signatures are declared through distinct signature_type values rather than being inferred from the signature bytes. Draft v0.1 does not fix which smart-account standard is approved, nor a production chain ID or verifying contract — those remain configuration placeholders.
Replay prevention summary
| Layer | Replay control |
|---|---|
| Canonical request signature | T17-Access-Timestamp clock-skew window + rejection of a reused T17-Access-Nonce |
| Mutating request | Required Idempotency-Key; identical replay returns the original result, mismatched replay returns IDEMPOTENCY_CONFLICT |
T17ApiAuthorization | nonce + expiry inside the signed payload |
T17Order | nonce + expiry (for GTD) inside the signed payload |
Where to go next
- Getting Started → Authentication preparation for safe credential-handling guidance before you integrate.
- Orders for how request authentication and order authorization combine in the validation pipeline.
- Errors for the
AUTH_*,SIGNATURE_*, andREPLAY_*error families.