{"openapi":"3.1.0","info":{"title":"Nora Yield","version":"1"},"tags":[{"name":"Authentication","description":"Every request must include an API key in the `x-api-key` header. Create and manage API keys in the dashboard."},{"name":"Conventions","description":"### Amounts\n\nAll amounts are expressed in BRS and sent as decimal strings. Requests accept up to two decimal places, and responses are returned with six.\n\nEvery value computed from the `terms` of an offer is truncated to the centavo once, on the whole `principal` of the position.\n\n### Dates\n\nDates without a time (`YYYY-MM-DD`) are in São Paulo time. Business days exclude weekends and Brazilian bank holidays.\n\n### Terms\n\n`index` and `payoutDelay.unit` are strings. Each names the convention the fields next to it are read under, and its description lists the values known today. A value may be added without a new version of the API. Do not show or sell an offer whose `terms` carry a value you do not know. [`GET /v1/offers`](#tag/endpoints/GET/v1/offers) takes an `index` to list only the offers you do."},{"name":"Endpoints"},{"name":"Errors","description":"The API uses conventional HTTP response codes to indicate the success or failure of a request. In general:\n\n- Codes in the `2xx` range indicate success.\n- Codes in the `4xx` range indicate a request that could not be fulfilled given the information provided.\n  - A `422` means the request is valid, but cannot be fulfilled in the current state.\n- Codes in the `5xx` range indicate a failure on Nora's side or in a service it depends on.\n\n### Error responses\n\nEvery error response uses this envelope:\n\n```json\n{\n  \"code\": \"AMOUNT_BELOW_MINIMUM\",\n  \"message\": \"amount must be at least 100.000000 BRS\",\n  \"details\": {\n    \"minimumOrderAmount\": \"100.000000\",\n    \"maximumOrderAmount\": \"5000.000000\"\n  }\n}\n```\n\n- `code` identifies the error. It is stable and always comes with the same HTTP status.\n- `message` describes the error for a human reader. The wording may change.\n- `details` is only present for some codes and includes information to act on the error. Its fields are specific to the code.\n\nThe codes each endpoint can return are listed in its definition."}],"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"x-api-key"}}},"security":[{"apiKey":[]}],"paths":{"/v1/offers":{"get":{"summary":"List offers","description":"Lists offers from newest to oldest.","tags":["Endpoints"],"parameters":[{"name":"index","in":"query","required":false,"schema":{"description":"Lists only the offers on this index.","type":"string","maxLength":32}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"array","items":{"type":"object","properties":{"offerId":{"type":"string","description":"Identifies the offer in every other call."},"name":{"type":"string"},"symbol":{"type":"string"},"receiptMint":{"type":"string","description":"The Solana address of the Token-2022 mint of the offer's receipt token. Each confirmed order mints the order's amount of it to the wallet. The token cannot be transferred."},"description":{"type":"string","description":"A plain-text description of the offer. It is never empty, and line breaks in it separate paragraphs."},"company":{"type":"object","properties":{"name":{"type":"string","description":"The name the company trades under."},"description":{"type":"string","description":"A plain-text description of the company, up to 280 characters."},"logoUrl":{"type":"string","description":"A square PNG or WebP image of the company's logo. The URL changes when the logo changes."},"websiteUrl":{"type":"string","description":"The company's website."}},"required":["name","description","logoUrl","websiteUrl"],"additionalProperties":false,"description":"The company offering this investment product."},"status":{"type":"string","enum":["upcoming","open","closing","confirmed","cancelled","matured"],"description":"`upcoming` → `open` → `closing` → `confirmed` → `matured`  \n`upcoming` → `open` → `closing` → `cancelled`\n\n- `upcoming`. Orders are accepted from `buyWindowStart`.\n- `open`. Orders are accepted.\n- `closing`. Orders are no longer accepted. Whether the offer reached `minimumRaise` is decided once its last orders settle, usually minutes after `buyWindowEnd`.\n- `confirmed`. The offer reached `minimumRaise`. Positions are held to `maturity`.\n- `cancelled`. The offer sold less than `minimumRaise`. Every position is refunded, and the refunds are listed by [`GET /v1/redemptions`](#tag/endpoints/GET/v1/redemptions) with `kind: refund`.\n- `matured`. From `maturity` on, once `confirmed`."},"buyWindowStart":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first day orders are accepted, inclusive."},"buyWindowEnd":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first day orders are no longer accepted, so the window excludes it."},"accrualStart":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first day interest accrues. Interest accrues from the start of this day to the start of `maturity`, as the description of the [`index`](#tag/endpoints/GET/v1/offers) field states."},"maturity":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The date the payout of each position is due."},"terms":{"type":"object","properties":{"index":{"type":"string","description":"Defines the convention used to interpret rates and calculate accrued returns. Additional conventions may be introduced as described in [Conventions](#tag/conventions).\n\n#### `cdi`\n\nFloating rate indexed to B3's DI rate, compounded daily over business days.\n\n- **Rate:** `percentOfIndex` scales each daily DI rate before compounding. `fixedRate` is an additional annual rate, compounded independently and applied multiplicatively to the indexed return.\n- **Accrual:** Daily compounding over business days, using a 252-business-day year (BUS/252).\n- **Valuation:** Counts the business days before the valuation date in the `America/Sao_Paulo` time zone.\n- **Projection:** Future business days use the latest published daily DI rate until new rates become available.\n- **Example:** At 15% annual DI, `percentOfIndex: 90.00` yields approximately 13.40% over 252 business days. With `percentOfIndex: 100.00` and `fixedRate: 2.00`, the combined return over 252 business days is 17.30%.\n\n#### `fixed_exp365_seconds`\n\nFixed effective annual rate, compounded every second on a 365-day year.\n\n- **Rate:** `fixedRate` defines the total effective annual return (APY). `percentOfIndex` does not apply.\n- **Accrual:** Compounding is based on actual elapsed seconds, using a fixed 365-day year (ACT/365F), equivalent to 31,536,000 seconds. All elapsed time counts, including February 29, without adjusting the annual denominator for leap years.\n- **Valuation:** Accrual starts at 00:00 on `accrualStart` and ends at the valuation instant, capped at 00:00 on `maturity`. Both dates are interpreted in `America/Sao_Paulo`. No intermediate rounding is applied.\n- **Projection:** Returns are deterministic and require no external rate data. `estimated` is always `false`, and `projectedMaturityValue` is the payout at `maturity`.\n- **Early exit:** The payout is calculated at the time of the exit request. It may exceed a previously quoted `earlyExit.payoutAmount`, but cannot be lower.\n- **Example:** A `fixedRate` of `18.00` yields approximately 8.60% over 182 elapsed days, exactly 18.00% over 365 elapsed days, and approximately 18.05% over 366 elapsed days."},"atMaturity":{"type":"object","properties":{"percentOfIndex":{"description":"The share of the index the position earns, in percent (`100.00` is the whole of it). The description of the `index` field states whether it applies, and how. When it does not apply, this field is absent.","type":"string"},"fixedRate":{"type":"string","description":"The fixed annual rate, in percent. The description of the `index` field states how it is compounded."}},"required":["fixedRate"],"additionalProperties":false},"earlyExit":{"anyOf":[{"type":"object","properties":{"percentOfIndex":{"description":"The share of the index the position earns, in percent (`100.00` is the whole of it). The description of the `index` field states whether it applies, and how. When it does not apply, this field is absent.","type":"string"},"fixedRate":{"type":"string","description":"The fixed annual rate, in percent. The description of the `index` field states how it is compounded."},"payoutDelay":{"type":"object","properties":{"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unit":{"type":"string","description":"- `business_days`. `count` business days after the business day of the request. A request on a weekend or holiday is counted from the next business day."}},"required":["count","unit"],"additionalProperties":false,"description":"How long after the request the payout is due."},"requestableUntil":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"The last day an early exit can be requested, inclusive. It is `null` when no day of the offer qualifies, because every payout would fall on or after `maturity`."}},"required":["fixedRate","payoutDelay","requestableUntil"],"additionalProperties":false},{"type":"null"}],"description":"It is `null` when the offer has no early exit."}},"required":["index","atMaturity","earlyExit"],"additionalProperties":false,"description":"The return of a position held to maturity, and the terms of an early exit."},"minimumOrderAmount":{"type":"string","description":"The smallest order the offer accepts."},"maximumPerWallet":{"type":"string","description":"The most one wallet can hold in the offer, across its orders."},"minimumRaise":{"type":"string","description":"The least the offer must have sold when its window closes. Below it, the offer is `cancelled` and every position is refunded."},"maximumRaise":{"type":"string","description":"The most the offer can sell."},"available":{"type":"string","description":"What is left in the offer. Pending orders count against it until they expire."}},"required":["offerId","name","symbol","receiptMint","description","company","status","buyWindowStart","buyWindowEnd","accrualStart","maturity","terms","minimumOrderAmount","maximumPerWallet","minimumRaise","maximumRaise","available"],"additionalProperties":false}}}}},"400":{"description":"INVALID_REQUEST","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"INVALID_REQUEST"},"message":{"type":"string"},"details":{"type":"object","properties":{"issues":{"minItems":1,"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"The query parameter, or a JSON Pointer to the field in the body."},"code":{"type":"string","enum":["MISSING","INVALID_TYPE","INVALID_FORMAT","INVALID_VALUE"]},"message":{"type":"string"}},"required":["path","code","message"],"additionalProperties":false}}},"required":["issues"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"INVALID_REQUEST"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"UNAUTHORIZED"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"UNAUTHORIZED"}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"INTERNAL_ERROR"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"INTERNAL_ERROR"}}}}}}},"/v1/offers/{offerId}":{"get":{"summary":"Retrieve an offer","tags":["Endpoints"],"parameters":[{"name":"offerId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"offerId":{"type":"string","description":"Identifies the offer in every other call."},"name":{"type":"string"},"symbol":{"type":"string"},"receiptMint":{"type":"string","description":"The Solana address of the Token-2022 mint of the offer's receipt token. Each confirmed order mints the order's amount of it to the wallet. The token cannot be transferred."},"description":{"type":"string","description":"A plain-text description of the offer. It is never empty, and line breaks in it separate paragraphs."},"company":{"type":"object","properties":{"name":{"type":"string","description":"The name the company trades under."},"description":{"type":"string","description":"A plain-text description of the company, up to 280 characters."},"logoUrl":{"type":"string","description":"A square PNG or WebP image of the company's logo. The URL changes when the logo changes."},"websiteUrl":{"type":"string","description":"The company's website."}},"required":["name","description","logoUrl","websiteUrl"],"additionalProperties":false,"description":"The company offering this investment product."},"status":{"type":"string","enum":["upcoming","open","closing","confirmed","cancelled","matured"],"description":"`upcoming` → `open` → `closing` → `confirmed` → `matured`  \n`upcoming` → `open` → `closing` → `cancelled`\n\n- `upcoming`. Orders are accepted from `buyWindowStart`.\n- `open`. Orders are accepted.\n- `closing`. Orders are no longer accepted. Whether the offer reached `minimumRaise` is decided once its last orders settle, usually minutes after `buyWindowEnd`.\n- `confirmed`. The offer reached `minimumRaise`. Positions are held to `maturity`.\n- `cancelled`. The offer sold less than `minimumRaise`. Every position is refunded, and the refunds are listed by [`GET /v1/redemptions`](#tag/endpoints/GET/v1/redemptions) with `kind: refund`.\n- `matured`. From `maturity` on, once `confirmed`."},"buyWindowStart":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first day orders are accepted, inclusive."},"buyWindowEnd":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first day orders are no longer accepted, so the window excludes it."},"accrualStart":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first day interest accrues. Interest accrues from the start of this day to the start of `maturity`, as the description of the [`index`](#tag/endpoints/GET/v1/offers) field states."},"maturity":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The date the payout of each position is due."},"terms":{"type":"object","properties":{"index":{"type":"string","description":"Defines the convention used to interpret rates and calculate accrued returns. Additional conventions may be introduced as described in [Conventions](#tag/conventions).\n\n#### `cdi`\n\nFloating rate indexed to B3's DI rate, compounded daily over business days.\n\n- **Rate:** `percentOfIndex` scales each daily DI rate before compounding. `fixedRate` is an additional annual rate, compounded independently and applied multiplicatively to the indexed return.\n- **Accrual:** Daily compounding over business days, using a 252-business-day year (BUS/252).\n- **Valuation:** Counts the business days before the valuation date in the `America/Sao_Paulo` time zone.\n- **Projection:** Future business days use the latest published daily DI rate until new rates become available.\n- **Example:** At 15% annual DI, `percentOfIndex: 90.00` yields approximately 13.40% over 252 business days. With `percentOfIndex: 100.00` and `fixedRate: 2.00`, the combined return over 252 business days is 17.30%.\n\n#### `fixed_exp365_seconds`\n\nFixed effective annual rate, compounded every second on a 365-day year.\n\n- **Rate:** `fixedRate` defines the total effective annual return (APY). `percentOfIndex` does not apply.\n- **Accrual:** Compounding is based on actual elapsed seconds, using a fixed 365-day year (ACT/365F), equivalent to 31,536,000 seconds. All elapsed time counts, including February 29, without adjusting the annual denominator for leap years.\n- **Valuation:** Accrual starts at 00:00 on `accrualStart` and ends at the valuation instant, capped at 00:00 on `maturity`. Both dates are interpreted in `America/Sao_Paulo`. No intermediate rounding is applied.\n- **Projection:** Returns are deterministic and require no external rate data. `estimated` is always `false`, and `projectedMaturityValue` is the payout at `maturity`.\n- **Early exit:** The payout is calculated at the time of the exit request. It may exceed a previously quoted `earlyExit.payoutAmount`, but cannot be lower.\n- **Example:** A `fixedRate` of `18.00` yields approximately 8.60% over 182 elapsed days, exactly 18.00% over 365 elapsed days, and approximately 18.05% over 366 elapsed days."},"atMaturity":{"type":"object","properties":{"percentOfIndex":{"description":"The share of the index the position earns, in percent (`100.00` is the whole of it). The description of the `index` field states whether it applies, and how. When it does not apply, this field is absent.","type":"string"},"fixedRate":{"type":"string","description":"The fixed annual rate, in percent. The description of the `index` field states how it is compounded."}},"required":["fixedRate"],"additionalProperties":false},"earlyExit":{"anyOf":[{"type":"object","properties":{"percentOfIndex":{"description":"The share of the index the position earns, in percent (`100.00` is the whole of it). The description of the `index` field states whether it applies, and how. When it does not apply, this field is absent.","type":"string"},"fixedRate":{"type":"string","description":"The fixed annual rate, in percent. The description of the `index` field states how it is compounded."},"payoutDelay":{"type":"object","properties":{"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unit":{"type":"string","description":"- `business_days`. `count` business days after the business day of the request. A request on a weekend or holiday is counted from the next business day."}},"required":["count","unit"],"additionalProperties":false,"description":"How long after the request the payout is due."},"requestableUntil":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"The last day an early exit can be requested, inclusive. It is `null` when no day of the offer qualifies, because every payout would fall on or after `maturity`."}},"required":["fixedRate","payoutDelay","requestableUntil"],"additionalProperties":false},{"type":"null"}],"description":"It is `null` when the offer has no early exit."}},"required":["index","atMaturity","earlyExit"],"additionalProperties":false,"description":"The return of a position held to maturity, and the terms of an early exit."},"minimumOrderAmount":{"type":"string","description":"The smallest order the offer accepts."},"maximumPerWallet":{"type":"string","description":"The most one wallet can hold in the offer, across its orders."},"minimumRaise":{"type":"string","description":"The least the offer must have sold when its window closes. Below it, the offer is `cancelled` and every position is refunded."},"maximumRaise":{"type":"string","description":"The most the offer can sell."},"available":{"type":"string","description":"What is left in the offer. Pending orders count against it until they expire."}},"required":["offerId","name","symbol","receiptMint","description","company","status","buyWindowStart","buyWindowEnd","accrualStart","maturity","terms","minimumOrderAmount","maximumPerWallet","minimumRaise","maximumRaise","available"],"additionalProperties":false}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"UNAUTHORIZED"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"UNAUTHORIZED"}}}},"404":{"description":"OFFER_NOT_FOUND","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"OFFER_NOT_FOUND"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"OFFER_NOT_FOUND"}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"INTERNAL_ERROR"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"INTERNAL_ERROR"}}}}}}},"/v1/order":{"post":{"summary":"Create an order","description":"Reserves the amount in the offer and returns the transaction the wallet must sign. The reservation is released if the order is not executed before `lastValidBlockHeight`.","tags":["Endpoints"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"offerId":{"type":"string","maxLength":32},"wallet":{"type":"string","maxLength":44,"description":"The wallet buying the position. It signs the transaction, pays the network fee in SOL, and receives a receipt token for the position."},"amount":{"type":"string","pattern":"^\\d{1,12}(\\.\\d{1,2})?$"}},"required":["offerId","wallet","amount"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"orderId":{"type":"string","description":"Identifies the order. It is passed to `POST /v1/execute` along with the signed transaction."},"offerId":{"type":"string"},"wallet":{"type":"string"},"amount":{"type":"string"},"lastValidBlockHeight":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The last block height at which the transaction can land. Past it, the order expires and its reservation is released."},"transaction":{"type":"string","description":"The transaction for the wallet to sign, as a base64-encoded Solana `VersionedTransaction`."}},"required":["orderId","offerId","wallet","amount","lastValidBlockHeight","transaction"],"additionalProperties":false}}}},"400":{"description":"INVALID_REQUEST, INVALID_JSON","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","oneOf":[{"type":"object","properties":{"code":{"type":"string","const":"INVALID_REQUEST"},"message":{"type":"string"},"details":{"type":"object","properties":{"issues":{"minItems":1,"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"The query parameter, or a JSON Pointer to the field in the body."},"code":{"type":"string","enum":["MISSING","INVALID_TYPE","INVALID_FORMAT","INVALID_VALUE"]},"message":{"type":"string"}},"required":["path","code","message"],"additionalProperties":false}}},"required":["issues"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"INVALID_REQUEST"},{"type":"object","properties":{"code":{"type":"string","const":"INVALID_JSON"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"INVALID_JSON"}]}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"UNAUTHORIZED"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"UNAUTHORIZED"}}}},"404":{"description":"OFFER_NOT_FOUND","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"OFFER_NOT_FOUND"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"OFFER_NOT_FOUND"}}}},"422":{"description":"OFFER_NOT_OPEN, OFFER_CLOSED, OFFER_CAPACITY_REACHED, WALLET_LIMIT_REACHED, AMOUNT_BELOW_MINIMUM, AMOUNT_ABOVE_WALLET_LIMIT, AMOUNT_ABOVE_OFFER_CAPACITY, INVALID_WALLET, INSUFFICIENT_BALANCE","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","oneOf":[{"type":"object","properties":{"code":{"type":"string","const":"OFFER_NOT_OPEN"},"message":{"type":"string"},"details":{"type":"object","properties":{"buyWindowStart":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first day orders are accepted, inclusive."},"buyWindowEnd":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first day orders are no longer accepted, so the window excludes it."}},"required":["buyWindowStart","buyWindowEnd"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"OFFER_NOT_OPEN","description":"The offer does not accept orders yet. It has not been launched, or today is before `buyWindowStart`."},{"type":"object","properties":{"code":{"type":"string","const":"OFFER_CLOSED"},"message":{"type":"string"},"details":{"type":"object","properties":{"buyWindowStart":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first day orders are accepted, inclusive."},"buyWindowEnd":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first day orders are no longer accepted, so the window excludes it."}},"required":["buyWindowStart","buyWindowEnd"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"OFFER_CLOSED","description":"The offer no longer accepts orders: today is `buyWindowEnd` or later."},{"type":"object","properties":{"code":{"type":"string","const":"OFFER_CAPACITY_REACHED"},"message":{"type":"string"},"details":{"type":"object","properties":{"minimumOrderAmount":{"type":"string","description":"The smallest order the offer accepts."},"maximumOrderAmount":{"type":"string","description":"The largest order this wallet can place right now, limited by the wallet's own limit and by what is left in the offer. Pending orders count against both until they expire."}},"required":["minimumOrderAmount","maximumOrderAmount"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"OFFER_CAPACITY_REACHED","description":"Less than `minimumOrderAmount` is left in the offer, so no order can be placed."},{"type":"object","properties":{"code":{"type":"string","const":"WALLET_LIMIT_REACHED"},"message":{"type":"string"},"details":{"type":"object","properties":{"minimumOrderAmount":{"type":"string","description":"The smallest order the offer accepts."},"maximumOrderAmount":{"type":"string","description":"The largest order this wallet can place right now, limited by the wallet's own limit and by what is left in the offer. Pending orders count against both until they expire."}},"required":["minimumOrderAmount","maximumOrderAmount"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"WALLET_LIMIT_REACHED","description":"The wallet can buy less than `minimumOrderAmount` more in this offer, so no order can be placed."},{"type":"object","properties":{"code":{"type":"string","const":"AMOUNT_BELOW_MINIMUM"},"message":{"type":"string"},"details":{"type":"object","properties":{"minimumOrderAmount":{"type":"string","description":"The smallest order the offer accepts."},"maximumOrderAmount":{"type":"string","description":"The largest order this wallet can place right now, limited by the wallet's own limit and by what is left in the offer. Pending orders count against both until they expire."}},"required":["minimumOrderAmount","maximumOrderAmount"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"AMOUNT_BELOW_MINIMUM"},{"type":"object","properties":{"code":{"type":"string","const":"AMOUNT_ABOVE_WALLET_LIMIT"},"message":{"type":"string"},"details":{"type":"object","properties":{"minimumOrderAmount":{"type":"string","description":"The smallest order the offer accepts."},"maximumOrderAmount":{"type":"string","description":"The largest order this wallet can place right now, limited by the wallet's own limit and by what is left in the offer. Pending orders count against both until they expire."}},"required":["minimumOrderAmount","maximumOrderAmount"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"AMOUNT_ABOVE_WALLET_LIMIT","description":"The amount is above `maximumOrderAmount`, which is set by the wallet's limit in this offer."},{"type":"object","properties":{"code":{"type":"string","const":"AMOUNT_ABOVE_OFFER_CAPACITY"},"message":{"type":"string"},"details":{"type":"object","properties":{"minimumOrderAmount":{"type":"string","description":"The smallest order the offer accepts."},"maximumOrderAmount":{"type":"string","description":"The largest order this wallet can place right now, limited by the wallet's own limit and by what is left in the offer. Pending orders count against both until they expire."}},"required":["minimumOrderAmount","maximumOrderAmount"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"AMOUNT_ABOVE_OFFER_CAPACITY","description":"The amount is above `maximumOrderAmount`, which is set by what is left in the offer."},{"type":"object","properties":{"code":{"type":"string","const":"INVALID_WALLET"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"INVALID_WALLET","description":"The wallet cannot buy (for example: because it is an off-curve address, which cannot sign)."},{"type":"object","properties":{"code":{"type":"string","const":"INSUFFICIENT_BALANCE"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"INSUFFICIENT_BALANCE"}]}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"INTERNAL_ERROR"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"INTERNAL_ERROR"}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"UPSTREAM_ERROR"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"UPSTREAM_ERROR","description":"The Solana RPC failed. Nothing changed."}}}}}}},"/v1/execute":{"post":{"summary":"Execute an order","description":"Submits the signed transaction and waits for it to settle. If it has not settled by the end of the wait, the response is a `202`. To check on the order later, call this endpoint again with the same signed transaction. Only the first signed transaction Nora records can land, so calling again never results in a second purchase.\n\nA `2xx` means the BRS was bought, or still can be. A `4xx` means nothing was bought on this request. A `422` says whether the same order can be executed again or a new one is needed.","tags":["Endpoints"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"signedTransaction":{"type":"string","maxLength":4096,"description":"The order's transaction, signed by the wallet and base64-encoded. The wallet may add, change or remove Compute Budget instructions, add Lighthouse instructions that name no signer other than itself, and reorder the accounts; any other change is `TRANSACTION_MISMATCH`."},"orderId":{"type":"string","maxLength":64}},"required":["signedTransaction","orderId"]}}}},"responses":{"200":{"description":"The purchase landed.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"orderId":{"type":"string","description":"Identifies the order. It is passed to `POST /v1/execute` along with the signed transaction."},"offerId":{"type":"string"},"wallet":{"type":"string"},"amount":{"type":"string"},"lastValidBlockHeight":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The last block height at which the transaction can land. Past it, the order expires and its reservation is released."},"status":{"type":"string","const":"confirmed"},"signature":{"type":"string"},"slot":{"type":"string"}},"required":["orderId","offerId","wallet","amount","lastValidBlockHeight","status","signature","slot"],"additionalProperties":false,"title":"confirmed","description":"The transaction landed. The BRS was transferred from the wallet, and a receipt token for the same amount was minted to it."}}}},"202":{"description":"The order is still pending.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"orderId":{"type":"string","description":"Identifies the order. It is passed to `POST /v1/execute` along with the signed transaction."},"offerId":{"type":"string"},"wallet":{"type":"string"},"amount":{"type":"string"},"lastValidBlockHeight":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"The last block height at which the transaction can land. Past it, the order expires and its reservation is released."},"status":{"type":"string","const":"pending"},"signature":{"type":"string"}},"required":["orderId","offerId","wallet","amount","lastValidBlockHeight","status","signature"],"additionalProperties":false,"title":"pending","description":"The transaction was sent and has not settled yet."}}}},"400":{"description":"INVALID_REQUEST, INVALID_JSON","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","oneOf":[{"type":"object","properties":{"code":{"type":"string","const":"INVALID_REQUEST"},"message":{"type":"string"},"details":{"type":"object","properties":{"issues":{"minItems":1,"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"The query parameter, or a JSON Pointer to the field in the body."},"code":{"type":"string","enum":["MISSING","INVALID_TYPE","INVALID_FORMAT","INVALID_VALUE"]},"message":{"type":"string"}},"required":["path","code","message"],"additionalProperties":false}}},"required":["issues"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"INVALID_REQUEST"},{"type":"object","properties":{"code":{"type":"string","const":"INVALID_JSON"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"INVALID_JSON"}]}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"UNAUTHORIZED"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"UNAUTHORIZED"}}}},"404":{"description":"ORDER_NOT_FOUND","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"ORDER_NOT_FOUND"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"ORDER_NOT_FOUND","description":"No order you created has this `orderId`."}}}},"422":{"description":"TRANSACTION_MISMATCH, ORDER_EXPIRED, ORDER_FAILED, TRANSACTION_NOT_SIGNED, TRANSACTION_REJECTED","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","oneOf":[{"type":"object","properties":{"code":{"type":"string","const":"TRANSACTION_MISMATCH"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"TRANSACTION_MISMATCH","description":"The signed transaction does not belong to this order. Execute again with the right transaction."},{"type":"object","properties":{"code":{"type":"string","const":"ORDER_EXPIRED"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"ORDER_EXPIRED","description":"The order expired before its transaction landed. No BRS was moved. Place a new order."},{"type":"object","properties":{"code":{"type":"string","const":"ORDER_FAILED"},"message":{"type":"string"},"details":{"type":"object","properties":{"signature":{"type":"string"},"networkError":{"type":"string","description":"The error the network reported for the transaction."}},"required":["signature","networkError"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"ORDER_FAILED","description":"The transaction landed but failed on chain. No BRS was moved, but the wallet paid the network fee. Place a new order."},{"type":"object","properties":{"code":{"type":"string","const":"TRANSACTION_NOT_SIGNED"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"TRANSACTION_NOT_SIGNED","description":"The transaction is not signed by the order's wallet. Execute again with a transaction it signed."},{"type":"object","properties":{"code":{"type":"string","const":"TRANSACTION_REJECTED"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"TRANSACTION_REJECTED","description":"The network refused the transaction (for example: because the wallet lacks SOL for the fee). Execute again with the same signed transaction."}]}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"INTERNAL_ERROR"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"INTERNAL_ERROR"}}}},"502":{"description":"UPSTREAM_ERROR","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"UPSTREAM_ERROR"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"UPSTREAM_ERROR","description":"The Solana RPC failed. Nothing changed."}}}}}}},"/v1/positions":{"get":{"summary":"List positions","description":"Lists the wallet's positions from the newest offer to the oldest, each valued at `asOf`. A position sums the confirmed orders the wallet placed in one offer through you, and its `offerId` and `wallet` identify it.\n\nA position leaves this list once a redemption is scheduled for it, and comes back if that redemption is `cancelled`. While it is out, [`GET /v1/redemptions`](#tag/endpoints/GET/v1/redemptions) filtered by its `offerId` and `wallet` tracks it.","tags":["Endpoints"],"parameters":[{"name":"wallet","in":"query","required":true,"schema":{"type":"string","maxLength":44}},{"name":"offerId","in":"query","required":false,"schema":{"type":"string","maxLength":32}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"array","items":{"type":"object","properties":{"offerId":{"type":"string"},"wallet":{"type":"string"},"principal":{"type":"string","description":"The total amount of the position's orders."},"accrualStart":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first day interest accrues. Interest accrues from the start of this day to the start of `maturity`, as the description of the [`index`](#tag/endpoints/GET/v1/offers) field states."},"maturity":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The date the payout of the position is due."},"currentValue":{"type":"string","description":"The `principal` plus the interest accrued before `asOf`, at the offer's `terms.atMaturity`. An early exit pays `earlyExit.payoutAmount` instead."},"projectedMaturityValue":{"type":"string","description":"The projected payout at `maturity`. The description of the [`index`](#tag/endpoints/GET/v1/offers) field states how it is projected for that index."},"earlyExit":{"anyOf":[{"type":"object","properties":{"payoutAmount":{"type":"string","description":"The amount an early exit requested at `asOf` would pay, at the offer's `terms.earlyExit`. It is reported on every day, including the days `requestable` is `false`. From `maturity` on it equals `currentValue`."},"payoutDelay":{"type":"object","properties":{"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unit":{"type":"string","description":"- `business_days`. `count` business days after the business day of the request. A request on a weekend or holiday is counted from the next business day."}},"required":["count","unit"],"additionalProperties":false,"description":"How long after the request the payout is due."},"requestable":{"type":"boolean","description":"Whether an early exit requested at `asOf` is accepted. It is `false` before `accrualStart` and while the offer is `closing`, after `requestableUntil` or always when it is `null`, and while `estimated` is `true`."},"requestableUntil":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"The last day an early exit can be requested, inclusive. It is `null` when no day of the offer qualifies, because every payout would fall on or after `maturity`."}},"required":["payoutAmount","payoutDelay","requestable","requestableUntil"],"additionalProperties":false},{"type":"null"}],"description":"It is `null` when the offer has no early exit."},"asOf":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"The instant of the request. Every value refers to it."},"estimated":{"type":"boolean","description":"Whether the values rely on a daily rate of the index that is not final yet, so they can still change. `earlyExit.requestable` is `false` while this is `true`."}},"required":["offerId","wallet","principal","accrualStart","maturity","currentValue","projectedMaturityValue","earlyExit","asOf","estimated"],"additionalProperties":false}}}}},"400":{"description":"INVALID_REQUEST","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"INVALID_REQUEST"},"message":{"type":"string"},"details":{"type":"object","properties":{"issues":{"minItems":1,"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"The query parameter, or a JSON Pointer to the field in the body."},"code":{"type":"string","enum":["MISSING","INVALID_TYPE","INVALID_FORMAT","INVALID_VALUE"]},"message":{"type":"string"}},"required":["path","code","message"],"additionalProperties":false}}},"required":["issues"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"INVALID_REQUEST"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"UNAUTHORIZED"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"UNAUTHORIZED"}}}},"404":{"description":"OFFER_NOT_FOUND","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"OFFER_NOT_FOUND"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"OFFER_NOT_FOUND"}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"INTERNAL_ERROR"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"INTERNAL_ERROR"}}}}}}},"/v1/redemptions":{"post":{"summary":"Request an early exit","description":"Schedules an early exit of the wallet's position in the offer, at the value of `earlyExit.payoutAmount` at the instant of the request (see [`GET /v1/positions`](#tag/endpoints/GET/v1/positions)). The request is accepted while the position's `earlyExit.requestable` is `true` (see [`GET /v1/positions`](#tag/endpoints/GET/v1/positions)). When `earlyExit` is `null` or `earlyExit.requestable` is `false`, this request is refused with the error code that explains its refusal.\n\nIf an early exit was already requested for the position, the call returns `200`. A position already redeemed by its maturity payout or by a refund is refused with `POSITION_REDEEMED`.\n\nNora pays the redemption by `payoutDueDate` and the position holder's wallet does not need to sign anything.","tags":["Endpoints"],"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"offerId":{"type":"string","maxLength":32},"wallet":{"type":"string","maxLength":44}},"required":["offerId","wallet"]}}}},"responses":{"200":{"description":"An early exit was already requested for the position.","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"redemptionId":{"type":"string"},"offerId":{"type":"string"},"wallet":{"type":"string"},"kind":{"type":"string","enum":["early_exit","maturity","refund"],"description":"- `early_exit`. Requested with `POST /v1/redemptions`. It pays the position's `earlyExit.payoutAmount` at the instant of the request.\n- `maturity`. Scheduled by Nora on `maturity`. It pays the position's `currentValue` on that day.\n- `refund`. Scheduled by Nora when the buy window closes with less than `minimumRaise` sold. It pays `principal` only."},"status":{"type":"string","enum":["scheduled","paid","cancelled"],"description":"- `scheduled`. Nora owes the payout and pays it by `payoutDueDate`.\n- `paid`. The BRS has reached the wallet.\n- `cancelled`. Nora cancelled the redemption. The position is open again."},"overdue":{"type":"boolean","description":"Whether `status` is still `scheduled` after `payoutDueDate`."},"principal":{"type":"string","description":"The `principal` of the position the redemption pays out. Receipt tokens up to this amount are burned from the wallet when the redemption is paid."},"yield":{"type":"string","description":"The interest the redemption pays on top of `principal`. It is 0 on a refund."},"payoutAmount":{"type":"string","description":"The amount paid to the wallet. It is `principal` plus `yield`, and it does not change once the redemption is created."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the redemption was created."},"payoutDueDate":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The date the payout is due. It does not move if the payout is late."},"payoutSignature":{"description":"The signature of the Solana transaction that paid the redemption. It is `null` unless `status` is `paid`.","type":["string","null"]}},"required":["redemptionId","offerId","wallet","kind","status","overdue","principal","yield","payoutAmount","createdAt","payoutDueDate","payoutSignature"],"additionalProperties":false}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"redemptionId":{"type":"string"},"offerId":{"type":"string"},"wallet":{"type":"string"},"kind":{"type":"string","enum":["early_exit","maturity","refund"],"description":"- `early_exit`. Requested with `POST /v1/redemptions`. It pays the position's `earlyExit.payoutAmount` at the instant of the request.\n- `maturity`. Scheduled by Nora on `maturity`. It pays the position's `currentValue` on that day.\n- `refund`. Scheduled by Nora when the buy window closes with less than `minimumRaise` sold. It pays `principal` only."},"status":{"type":"string","enum":["scheduled","paid","cancelled"],"description":"- `scheduled`. Nora owes the payout and pays it by `payoutDueDate`.\n- `paid`. The BRS has reached the wallet.\n- `cancelled`. Nora cancelled the redemption. The position is open again."},"overdue":{"type":"boolean","description":"Whether `status` is still `scheduled` after `payoutDueDate`."},"principal":{"type":"string","description":"The `principal` of the position the redemption pays out. Receipt tokens up to this amount are burned from the wallet when the redemption is paid."},"yield":{"type":"string","description":"The interest the redemption pays on top of `principal`. It is 0 on a refund."},"payoutAmount":{"type":"string","description":"The amount paid to the wallet. It is `principal` plus `yield`, and it does not change once the redemption is created."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the redemption was created."},"payoutDueDate":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The date the payout is due. It does not move if the payout is late."},"payoutSignature":{"description":"The signature of the Solana transaction that paid the redemption. It is `null` unless `status` is `paid`.","type":["string","null"]}},"required":["redemptionId","offerId","wallet","kind","status","overdue","principal","yield","payoutAmount","createdAt","payoutDueDate","payoutSignature"],"additionalProperties":false}}}},"400":{"description":"INVALID_REQUEST, INVALID_JSON","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","oneOf":[{"type":"object","properties":{"code":{"type":"string","const":"INVALID_REQUEST"},"message":{"type":"string"},"details":{"type":"object","properties":{"issues":{"minItems":1,"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"The query parameter, or a JSON Pointer to the field in the body."},"code":{"type":"string","enum":["MISSING","INVALID_TYPE","INVALID_FORMAT","INVALID_VALUE"]},"message":{"type":"string"}},"required":["path","code","message"],"additionalProperties":false}}},"required":["issues"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"INVALID_REQUEST"},{"type":"object","properties":{"code":{"type":"string","const":"INVALID_JSON"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"INVALID_JSON"}]}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"UNAUTHORIZED"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"UNAUTHORIZED"}}}},"404":{"description":"OFFER_NOT_FOUND, POSITION_NOT_FOUND","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","oneOf":[{"type":"object","properties":{"code":{"type":"string","const":"OFFER_NOT_FOUND"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"OFFER_NOT_FOUND"},{"type":"object","properties":{"code":{"type":"string","const":"POSITION_NOT_FOUND"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"POSITION_NOT_FOUND","description":"The wallet has no position in the offer that you sold."}]}}}},"422":{"description":"POSITION_REDEEMED, EARLY_EXIT_NOT_OFFERED, EARLY_EXIT_NOT_OPEN, EARLY_EXIT_CLOSED","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","oneOf":[{"type":"object","properties":{"code":{"type":"string","const":"POSITION_REDEEMED"},"message":{"type":"string"},"details":{"type":"object","properties":{"redemptionId":{"type":"string"},"kind":{"type":"string","enum":["maturity","refund"]}},"required":["redemptionId","kind"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"POSITION_REDEEMED","description":"The position was already redeemed, by its maturity payout or by a refund. `details` identifies that redemption."},{"type":"object","properties":{"code":{"type":"string","const":"EARLY_EXIT_NOT_OFFERED"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"EARLY_EXIT_NOT_OFFERED","description":"The offer has no early exit. The position is redeemed at maturity."},{"type":"object","properties":{"code":{"type":"string","const":"EARLY_EXIT_NOT_OPEN"},"message":{"type":"string"},"details":{"type":"object","properties":{"accrualStart":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first day interest accrues. Interest accrues from the start of this day to the start of `maturity`, as the description of the [`index`](#tag/endpoints/GET/v1/offers) field states."},"requestableUntil":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"The last day an early exit can be requested, inclusive. It is `null` when no day of the offer qualifies, because every payout would fall on or after `maturity`."}},"required":["accrualStart","requestableUntil"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"EARLY_EXIT_NOT_OPEN","description":"An early exit cannot be requested before `accrualStart`, nor while the offer is `closing`."},{"type":"object","properties":{"code":{"type":"string","const":"EARLY_EXIT_CLOSED"},"message":{"type":"string"},"details":{"type":"object","properties":{"accrualStart":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The first day interest accrues. Interest accrues from the start of this day to the start of `maturity`, as the description of the [`index`](#tag/endpoints/GET/v1/offers) field states."},"requestableUntil":{"anyOf":[{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"},{"type":"null"}],"description":"The last day an early exit can be requested, inclusive. It is `null` when no day of the offer qualifies, because every payout would fall on or after `maturity`."}},"required":["accrualStart","requestableUntil"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"EARLY_EXIT_CLOSED","description":"An early exit cannot be requested after `requestableUntil`. The position is redeemed at maturity."}]}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"INTERNAL_ERROR"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"INTERNAL_ERROR"}}}},"503":{"description":"SERVICE_UNAVAILABLE","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"SERVICE_UNAVAILABLE"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"SERVICE_UNAVAILABLE","description":"Nora cannot take the request right now, and nothing changed. Try again after the seconds in `Retry-After`."}}}}}},"get":{"summary":"List redemptions","description":"Lists every redemption of the positions you sold. This includes the early exits you requested as well as the maturity payouts and refunds Nora schedules on its own. Each redemption reports its `status` and `payoutDueDate`, so this endpoint can be used to track payouts to your users.\n\nResults can be filtered by offer, wallet and status.","tags":["Endpoints"],"parameters":[{"name":"offerId","in":"query","required":false,"schema":{"type":"string","maxLength":32}},{"name":"wallet","in":"query","required":false,"schema":{"type":"string","maxLength":44}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["scheduled","paid","cancelled"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"array","items":{"type":"object","properties":{"redemptionId":{"type":"string"},"offerId":{"type":"string"},"wallet":{"type":"string"},"kind":{"type":"string","enum":["early_exit","maturity","refund"],"description":"- `early_exit`. Requested with `POST /v1/redemptions`. It pays the position's `earlyExit.payoutAmount` at the instant of the request.\n- `maturity`. Scheduled by Nora on `maturity`. It pays the position's `currentValue` on that day.\n- `refund`. Scheduled by Nora when the buy window closes with less than `minimumRaise` sold. It pays `principal` only."},"status":{"type":"string","enum":["scheduled","paid","cancelled"],"description":"- `scheduled`. Nora owes the payout and pays it by `payoutDueDate`.\n- `paid`. The BRS has reached the wallet.\n- `cancelled`. Nora cancelled the redemption. The position is open again."},"overdue":{"type":"boolean","description":"Whether `status` is still `scheduled` after `payoutDueDate`."},"principal":{"type":"string","description":"The `principal` of the position the redemption pays out. Receipt tokens up to this amount are burned from the wallet when the redemption is paid."},"yield":{"type":"string","description":"The interest the redemption pays on top of `principal`. It is 0 on a refund."},"payoutAmount":{"type":"string","description":"The amount paid to the wallet. It is `principal` plus `yield`, and it does not change once the redemption is created."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the redemption was created."},"payoutDueDate":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The date the payout is due. It does not move if the payout is late."},"payoutSignature":{"description":"The signature of the Solana transaction that paid the redemption. It is `null` unless `status` is `paid`.","type":["string","null"]}},"required":["redemptionId","offerId","wallet","kind","status","overdue","principal","yield","payoutAmount","createdAt","payoutDueDate","payoutSignature"],"additionalProperties":false}}}}},"400":{"description":"INVALID_REQUEST","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"INVALID_REQUEST"},"message":{"type":"string"},"details":{"type":"object","properties":{"issues":{"minItems":1,"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"The query parameter, or a JSON Pointer to the field in the body."},"code":{"type":"string","enum":["MISSING","INVALID_TYPE","INVALID_FORMAT","INVALID_VALUE"]},"message":{"type":"string"}},"required":["path","code","message"],"additionalProperties":false}}},"required":["issues"],"additionalProperties":false}},"required":["code","message","details"],"additionalProperties":false,"title":"INVALID_REQUEST"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"UNAUTHORIZED"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"UNAUTHORIZED"}}}},"404":{"description":"OFFER_NOT_FOUND","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"OFFER_NOT_FOUND"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"OFFER_NOT_FOUND"}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"INTERNAL_ERROR"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"INTERNAL_ERROR"}}}}}}},"/v1/redemptions/{redemptionId}":{"get":{"summary":"Retrieve a redemption","tags":["Endpoints"],"parameters":[{"name":"redemptionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"redemptionId":{"type":"string"},"offerId":{"type":"string"},"wallet":{"type":"string"},"kind":{"type":"string","enum":["early_exit","maturity","refund"],"description":"- `early_exit`. Requested with `POST /v1/redemptions`. It pays the position's `earlyExit.payoutAmount` at the instant of the request.\n- `maturity`. Scheduled by Nora on `maturity`. It pays the position's `currentValue` on that day.\n- `refund`. Scheduled by Nora when the buy window closes with less than `minimumRaise` sold. It pays `principal` only."},"status":{"type":"string","enum":["scheduled","paid","cancelled"],"description":"- `scheduled`. Nora owes the payout and pays it by `payoutDueDate`.\n- `paid`. The BRS has reached the wallet.\n- `cancelled`. Nora cancelled the redemption. The position is open again."},"overdue":{"type":"boolean","description":"Whether `status` is still `scheduled` after `payoutDueDate`."},"principal":{"type":"string","description":"The `principal` of the position the redemption pays out. Receipt tokens up to this amount are burned from the wallet when the redemption is paid."},"yield":{"type":"string","description":"The interest the redemption pays on top of `principal`. It is 0 on a refund."},"payoutAmount":{"type":"string","description":"The amount paid to the wallet. It is `principal` plus `yield`, and it does not change once the redemption is created."},"createdAt":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$","description":"When the redemption was created."},"payoutDueDate":{"type":"string","format":"date","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$","description":"The date the payout is due. It does not move if the payout is late."},"payoutSignature":{"description":"The signature of the Solana transaction that paid the redemption. It is `null` unless `status` is `paid`.","type":["string","null"]}},"required":["redemptionId","offerId","wallet","kind","status","overdue","principal","yield","payoutAmount","createdAt","payoutDueDate","payoutSignature"],"additionalProperties":false}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"UNAUTHORIZED"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"UNAUTHORIZED"}}}},"404":{"description":"REDEMPTION_NOT_FOUND","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"REDEMPTION_NOT_FOUND"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"REDEMPTION_NOT_FOUND","description":"No redemption of a position you sold has this `redemptionId`."}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","const":"INTERNAL_ERROR"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false,"title":"INTERNAL_ERROR"}}}}}}}},"servers":[{"url":"https://tidy-dinosaur-442.convex.site"}]}