Version: 1.1 · Effective: 2026-09-25 · Applies to: https://yield.trdefi.com/api/ and https://yield.trdefi.com/v1/
The operating rules that apply to every client of the API. Read together with the Method of Statement (what the API is) and the Overall Scheme (the endpoints and the write path).
| Surface | Credential | Notes |
|---|---|---|
Read surface (GET /api/*) | None | Open. Rate-limited, and the limit is advertised on every reply. |
Write path (POST /v1/positions) | One API key, held server-side by the client | The key prepares unsigned transactions. It cannot sign, broadcast or move value. |
There is no signing grant. That is the point of the design. A signing grant would be a secret of ours that can move a client's money; instead the client signs with its own wallet and we never hold anything worth stealing. A leaked API key costs its owner a rate-limit abuse problem — never a token.
trd_live_<keyId>_<secret>
keyId — a short public identifier. Safe to log; it is what appears in our audit trail.secret — shown once, at issuance. We store only sha256(secret + salt) and cannot recover it.Authorization: Bearer trd_live_<keyId>_<secret>.trd_test_ instead of trd_live_.Request one at https://yield.trdefi.com/docs/api#access. Tell us who you are, what you are building and roughly what volume to expect. Keys are issued after a short manual review — we will not give a write key to an address we cannot reach. There is no self-service issuance, and no key is needed to read.
Every key carries an explicit set of scopes. A request outside its scopes is refused with 403.
| Scope | Grants |
|---|---|
read | Read the public catalogue. Not needed — the read surface is open — but a key that has it may be used to carry the read quota on the same credential. |
prepare | POST /v1/positions. The only scope that writes anything, and even it only prepares. |
admin | Manage the organisation's own keys and webhooks. Not granted on request; issued per organisation. |
A key with prepare alone cannot read the catalogue. A key with read alone cannot prepare. Request only what the integration needs.
| Environment | Base URL | Purpose |
|---|---|---|
| Production | https://yield.trdefi.com/api, https://yield.trdefi.com/v1 | Live data, live positions |
| Test | public test networks (trd_test_ keys) | Verifying integration code before pointing at production |
Read-side behaviour is identical across environments. A client should verify against the test environment first; writing integration code that only works in production is not supported. A live key refuses a test-network chain and a test key refuses a mainnet one.
GET. POST is accepted only on the write path. OPTIONS is answered for CORS preflight. Anything else returns 405 METHOD_NOT_ALLOWED.application/json; charset=utf-8.X-Request-Id. Quote it in any support request. The same id is echoed in the body of the reply.decimals — never parse them as floats. The write path takes amounts the same way: an integer string in base units, with the token's decimals resolved server-side from the live token registry, so a 6-decimal and an 18-decimal token can never be confused.Cache-Control. meta.cached tells you whether the reply was served from our short-lived cache. Clients are free to cache within the advertised window.Limits are enforced per credential and per bucket. Issuing more credentials does not raise them.
| Bucket | Limit | Window |
|---|---|---|
stats | 120 | 60 s |
badge | 120 | 60 s |
chains | 60 | 60 s |
quote | 60 | 60 s |
strategy-detail | 60 | 60 s |
strategies | 20 | 60 s |
prepare (POST /v1/positions) | agreed per key, default 6 | 60 s |
The headers are authoritative, not this table. Every reply carries:
RateLimit-Limit: 120
RateLimit-Remaining: 119
RateLimit-Reset: 42
RateLimit-Policy: stats;w=60;limit=120
RateLimit-Reset seconds.429, Retry-After is always present. Honour it.429 without backoff, and do not fan a single logical operation across many parallel requests to stay under the limit. Doing so is a breach of §10.RateLimit-Policy value reflecting it.Idempotency-Key header. A repeated request with the same key returns the original outcome rather than performing the action twice. Keys are retained for 24 hours.POST /v1/positions is idempotent by construction. Nothing is broadcast, so repeating a preparation is harmless. The salt is derived from (your key, Idempotency-Key), so the same key returns the same strategyHash and cannot create a second position. Use a new key to prepare a genuinely new position; omit the header entirely and every call creates one.error.retryable is true, or when no response was received at all. Use exponential backoff with jitter.5xx on a write consumes the key — the operation may or may not have been applied. Retry with the same key to get a definitive answer. Do not generate a fresh key for a retry.4xx other than 429. Correct the request first.Every error uses one envelope:
{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded for stats",
"requestId": "9f2c1d4e7a8b3c5d6e0f1a2b3c4d5e6f",
"retryable": true,
"documentation": "https://yield.trdefi.com/docs/api#rate_limited"
}
}
code, never on message. Messages are for humans and may change at any time.retryable. It is part of the contract.issues[] array with expected and actual values — an allowance that is too low, a balance that is too low, a chain that is not live, an expired preparation — so a client can correct the condition without contacting us.401, 403) never say whether a key exists. A wrong key and a revoked key return the same envelope.https://yield.trdefi.com/docs/api#errors.The write path returns unsigned transactions. Two consequences a client must accept:
Where a client subscribes to events, the following rules apply.
id./api/ and /v1/ are the current contract.410 Gone in this contract.A client must not:
A client must:
429 and 5xx with backoff rather than retry stormsWe record one row per API request so we can operate the service and measure the service level we publish. This is what is stored:
| Field | Stored as |
|---|---|
| Path, method, HTTP status, latency | as observed |
| Timestamp | UTC |
| Client IP address | sha256(ip + salt) — the raw address is never stored |
| Country | coarse, derived from the request |
| User agent | truncated to 200 characters |
| Origin / referer | truncated to 200 characters |
| API credential id | the keyId portion only — never the secret |
We do not store request bodies, query-string values, cookies, or any account data. Rows are deleted after 30 days. IPs are hashed precisely so that we can count distinct clients without holding personal data.
What a client can audit about itself: every call made with its key is attributable to the keyId in our log. Revoke a key and the abuse stops; the record of what it did remains for the retention window. That is the audit trail — it is per key, and it is why a shared key is a bad idea.
Aggregates may be used internally for capacity and SLO measurement, and may be published only in aggregate form that cannot identify a client.
A position created through TRDEFI — web app or API — carries a 0.05 % protocol fee embedded in the signed order data. It is not a separate transfer and not an invoice; it executes on-chain with the position. There is no tier and no parameter that waives it, and the integrator cannot remove it.
The integrator's own commission (makerFeeBps) is theirs to set and is independent of it. Full statement: Overall Scheme, Part 7.
| Channel | Use |
|---|---|
info@trdefi.com | Anything, including integration questions and key requests |
requestId in the error envelope | Always include it — it lets us find the exact call |
Include, in every support request: the X-Request-Id, the endpoint, the exact request (redact any credential), and the response body as received.
These rules may be updated. A change that materially affects an existing integration is announced with the same 90-day notice as a breaking API change. The current version is always published at
https://yield.trdefi.com/docs/general-rules with an effective date.
TRDEFI Ltd, London, United Kingdom. See also: Method of Statement, Overall Scheme.