TrueFillsBroker-Verified Trading Strategies

API reference · v1

Every endpoint, as it actually behaves.

The complete v1 surface: request fields, validation bounds, status codes and rate limits, documented from the running implementation. New here? Start with the quick start. Base URL for all paths: https://truefills.com.

Conventions

Strategies

Register a strategy and mint its creator API key. Requires a signed-in session, and the strategy belongs to that account from the moment it exists. The key appears once in this response and is stored only as a hash; it cannot be recovered. The strategy name as it appears in the URL (the slug field) is derived from the name you give: lowercased, non-alphanumerics collapsed to dashes, trimmed to 40 characters.

Endpoint

POSThttps://truefills.com/api/v1/strategies
Auth: session cookieRate limit: 5 registrations per hour per IP

Parameters

ParameterConstraints
namestringRequired. 60 characters or fewer after trimming. Must leave a URL name of at least 3 characters. Platform and route names are reserved, and the derived URL name must not already be taken, including by a strategy that has been deleted.

Example

curl -X POST https://truefills.com/api/v1/strategies \
  -H "Content-Type: application/json" \
  -H "Cookie: amx_session=<your session cookie>" \
  -d '{"name": "My Mean Reversion Strategy"}'

Success response (201)

{
  "slug": "my-mean-reversion-strategy",
  "name": "My Mean Reversion Strategy",
  "apiKey": "f3a9...48 hex characters",
  "note": "Store this key now; it is shown once. Post orders to /api/v1/strategies/my-mean-reversion-strategy/orders with Authorization: Bearer <key>."
}
Errors
  • 400 body is not JSON, or “name” is missing or not a string
  • 401 no signed-in session; create the strategy on your account page or send your session cookie
  • 409 name over 60 characters, URL name under 3 characters, reserved name, or that name already taken
  • 429 rate limit exceeded; honor Retry-After

Public list of all strategies: Printhouse first, then every registered user strategy. New user strategies start in mode “unverified”.

Endpoint

GEThttps://truefills.com/api/v1/strategies
Auth: none

Parameters

None.

Example

curl https://truefills.com/api/v1/strategies

Success response (200)

{
  "strategies": [
    { "slug": "printhouse", "name": "Printhouse", "flagship": true, "mode": "paper" },
    { "slug": "my-mean-reversion-strategy", "name": "My Mean Reversion Strategy", "createdAt": "2026-09-05T14:02:11.412Z", "mode": "unverified" }
  ]
}
Errors
  • none this endpoint always returns 200

Public record for one strategy. User strategies return registration data plus the head of their order chain. Printhouse's slug returns a richer record: live stats, the equity series, verification pointers and the URL of its published chain file. Responses may be cached for up to an hour.

Endpoint

GEThttps://truefills.com/api/v1/strategies/:slug
Auth: none

Parameters

None.

Example

curl https://truefills.com/api/v1/strategies/my-mean-reversion-strategy

Success response (200), user strategy

{
  "slug": "my-mean-reversion-strategy",
  "name": "My Mean Reversion Strategy",
  "mode": "unverified",
  "createdAt": "2026-09-05T14:02:11.412Z",
  "orderCount": 12,
  "chainHead": "9c41...hash of the latest sealed order, null when empty"
}

// GET https://truefills.com/api/v1/strategies/printhouse returns instead:
// { "slug", "name", "flagship": true, "mode", "startedLive",
//   "stats": { "equity", "totalPlPct", ... }, "equitySeries": [{ "date", "equity" }, ...],
//   "verification": { "source", "chain", "records" }, "chainUrl": "/chain/printhouse.jsonl" }
// Between the 16:00 bell and the broker publishing that day's close (the next
// morning), the last equitySeries point is the 16:00 reading and carries
// "provisional": true. The published close replaces it.
Errors
  • 404 unknown strategy name

Orders

Post a trade as your strategy makes it. Fills only: there are no limit or stop orders, and nothing you send sets the price. The server stamps refPrice, the market price observed on arrival, seals it with the order and appends both to the strategy's public hash chain, where they cannot be changed afterward.

Endpoint

POSThttps://truefills.com/api/v1/strategies/:slug/orders
Auth: Bearer creator key for this strategyRate limit: 60 order posts per minute per key

Parameters

ParameterConstraints
action"buy" | "sell"Required.
symbolstringRequired. Uppercase ticker matching ^[A-Z][A-Z0-9.]{0,9}$ (1 to 10 characters).
qtynumberRequired. Greater than 0, at most 10,000,000.
type"market"Optional, and market is the only value. A limit or stop order, or any price, is refused with 400.

Example

curl -X POST https://truefills.com/api/v1/strategies/my-mean-reversion-strategy/orders \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action":"buy","symbol":"AAPL","qty":10}'

Success response (201)

{
  "sealed": true,
  "order": {
    "seq": 12,
    "ts": "2026-09-05T14:31:07.412Z",
    "action": "buy",
    "symbol": "AAPL",
    "qty": 10,
    "type": "market",
    "refPrice": 150.02,
    "prevHash": "9c41...hash of the previous entry, GENESIS for the first",
    "hash": "e07b...sha256 over prevHash plus this order body"
  }
}
Errors
  • 400 body is not JSON, a field fails validation, or the order names a limit, stop or price; the error message says which
  • 401 invalid or missing API key for this strategy
  • 429 rate limit exceeded; honor Retry-After

refPrice is left out of the sealed entry only when no market price was observable on arrival.

The hash-chained order log for a strategy, oldest first, Printhouse included. Everyone gets each entry's sequence, time and hashes, so anyone can recompute the chain. The trade inside each entry (symbol, side, size, price) goes to the strategy's owner, paying subscribers and accounts running it, identified by session cookie or by the feed key of a paid subscription. A strategy with no price shows it to everyone.

Endpoint

GEThttps://truefills.com/api/v1/strategies/:slug/orders
Auth: none; session cookie or Bearer feed key for the trades

Parameters

None.

Example

curl https://truefills.com/api/v1/strategies/my-mean-reversion-strategy/orders \
  -H "Authorization: Bearer YOUR_FEED_KEY"

Success response (200), with access to the trades

{
  "orders": [
    {
      "seq": 0,
      "ts": "2026-09-04T19:55:01.002Z",
      "action": "buy",
      "symbol": "AAPL",
      "qty": 10,
      "type": "market",
      "refPrice": 149.87,
      "prevHash": "GENESIS",
      "hash": "9c41..."
    }
  ],
  "total": 1
}
Errors
  • 404 unknown strategy name

Without access each entry keeps seq, ts, prevHash and hash, with redacted: true, and the response adds gated: true and a note saying who sees the trades.

Subscriptions and feed

Mint a feed key for a strategy you pay for, so your own software can read its trades. Requires a signed-in session with an active paid subscription to that strategy; the key belongs to that account. Asking again returns the existing subscription with a 200 and no new key; keys cannot be recovered. Running a strategy shows its trades too, signed in, with no key.

Endpoint

POSThttps://truefills.com/api/v1/subscriptions
Auth: session cookieRate limit: 10 subscriptions per hour per IP

Parameters

ParameterConstraints
strategystringRequired. The strategy name as it appears in its address (its slug); lowercased server-side.

Example

curl -X POST https://truefills.com/api/v1/subscriptions \
  -H "Content-Type: application/json" \
  -H "Cookie: amx_session=<your session cookie>" \
  -d '{"strategy":"printhouse"}'

Success response (201; 200 if already subscribed)

{
  "subscriptionId": "3f0e8a4c-7c1d-4e9a-9f2b-1a6d8c0e5b42",
  "strategy": "printhouse",
  "apiKey": "b7d2...48 hex characters",
  "note": "Store this key now; it is shown once. Poll /api/v1/feed with Authorization: Bearer <key>. It reads the trades while the paid subscription is active."
}
Errors
  • 400 body is not JSON
  • 401 no signed-in session
  • 403 no active paid subscription to this strategy
  • 404 unknown strategy name
  • 429 rate limit exceeded; honor Retry-After

Latest orders for a strategy whose trades you may see: one you pay for, or one running in your account. Two ways in: the feed key of a paid subscription as a bearer token, or a signed-in session (add ?strategy=slug to pick one; Printhouse is the default). User strategies return their last 50 sealed orders. Printhouse returns live orders read directly from the broker when the connection is configured, otherwise an empty list with an explanatory note.

Endpoint

GEThttps://truefills.com/api/v1/feed
Auth: Bearer feed key, or session cookieRate limit: 60 reads per minute per key (or per session)

Parameters

None.

Example

curl https://truefills.com/api/v1/feed \
  -H "Authorization: Bearer YOUR_FEED_KEY"

Success response (200), user strategy

{
  "strategy": "my-mean-reversion-strategy",
  "orders": [ ...last 50 sealed orders, same shape as the public order log... ],
  "note": "Latest sealed orders for your subscribed strategy."
}

// Flagship feed entries come from the broker and look like:
// { "ts", "action", "symbol", "qty", "type", "limit"?, "stop"?, "status" }
Errors
  • 401 invalid feed key, or neither a key nor a signed-in session
  • 403 no active paid subscription behind the key, or the signed-in account neither pays for the strategy nor runs it
  • 429 rate limit exceeded; honor Retry-After
  • 503 Printhouse's broker feed temporarily unavailable; retry shortly

GET /api/v1/subscriptions serves the same handler; /api/v1/feed is the documented path.

Broker connections

Read-only account links power broker-sourced records. These endpoints use the signed-in browser session, not API keys: broker links belong to people, not strategies. Credentials are entered on the broker’s own portal, never here, and no order placement exists on this platform.

Registers the signed-in user with the broker-connection provider (once) and returns a one-time portal URL. Open it, pick your brokerage, sign in there; the link created is read-only.

Endpoint

POSThttps://truefills.com/api/v1/broker/connect
Auth: session cookie (signed-in user)Rate limit: 10 portal URLs per hour per IP

Parameters

None.

Example

curl -X POST https://truefills.com/api/v1/broker/connect \
  -H "Cookie: your TrueFills session"

Success response (200)

{
  "redirect": "https://app.snaptrade.com/connect?...one-time portal URL"
}
Errors
  • 401 sign in required
  • 429 rate limit exceeded; honor Retry-After
  • 502 the connection provider rejected the request; the error message says which step failed
  • 503 broker connections are not enabled yet on this deployment

Connected brokerage accounts for the signed-in user: institution, account name, balance. Read-only data. Returns linked: false with an empty list when no broker has been connected.

Endpoint

GEThttps://truefills.com/api/v1/broker/accounts
Auth: session cookie (signed-in user)

Parameters

None.

Example

curl https://truefills.com/api/v1/broker/accounts \
  -H "Cookie: your TrueFills session"

Success response (200)

{
  "linked": true,
  "accounts": [
    {
      "id": "acc_...",
      "name": "Individual",
      "institution": "Robinhood",
      "logo": "https://...institution logo, null when unknown",
      "balance": { "amount": 12450.33, "currency": "USD" }
    }
  ]
}
Errors
  • 401 sign in required
  • 503 broker connections are not enabled yet on this deployment

Public list of supported brokerages. Served from a committed snapshot when the live provider list is unavailable, so it never renders empty. Responses may be cached for up to an hour.

Endpoint

GEThttps://truefills.com/api/v1/broker/vendors
Auth: none

Parameters

None.

Example

curl https://truefills.com/api/v1/broker/vendors

Success response (200)

{
  "vendors": [
    { "slug": "SCHWAB", "name": "Schwab", "logo": "https://...or null" },
    { "slug": "FIDELITY", "name": "Fidelity", "logo": null }
  ]
}
Errors
  • none this endpoint always returns 200
Something undocumented? This page is written against the actual route implementations and kept in lockstep with them. If a response you receive does not match what is written here, that is a bug worth reporting: contact. For how verification works end to end, read the methodology.