{
  "info": {
    "_postman_id": "9e0baea6-5e64-5480-90de-06433a01a8a3",
    "name": "Kamui External API",
    "description": "Postman collection for the **Kamui External API** (vault and wallet data, and unsigned deposit and redeem request transactions), built from the OpenAPI spec version 1.0.0.\n\n## Getting started in Postman\n\n1. Import this collection and the **Kamui External API - Production** environment, then select the environment (top right).\n2. In the environment, paste your API key into the **Current value** of `partnerApiKey` (type *secret*). Kamui gives you the key once; keep it in a secret manager. Do not put it in an **Initial value**: initial values are shared when you share or export.\n3. Send **Health → health.ping**. A `200` with `\"status\": \"ok\"` means your key works.\n4. Set `walletAddress` to a wallet you want to read, then try the **Vaults** and **Users** requests.\n5. To build transactions, ask Kamui to enable transaction building for your API client. Then set `senderAddress`, `depositAmount` and `redeemShares` and try the **Transactions** requests. Until it is enabled, they answer `403 actions_not_enabled`.\n\nWithout the environment, set the same values in the collection's **Variables** tab. With the environment selected, its `partnerApiKey` wins, even when it is empty, so paste the key there.\n\nA `401 unauthorized` on every request means the key was not accepted: the environment is not selected, `partnerApiKey` is empty, the key is not the full `kmi_<id>_<secret>`, or it was issued for another Kamui environment than `baseUrl`, or it was revoked or has expired. The **Test Results** tab names the likely cause.\n\n### Variables\n\n| Variable | Default | Used by |\n| --- | --- | --- |\n| `baseUrl` | `https://api.kamui.finance/functions/v1/external-api` | every request |\n| `partnerApiKey` | empty | every request, sent as `x-partner-api-key` |\n| `vaultSlug` | `stable-vault` | `vaults.get`, `vaults.history`, the filtered `users.transactions`, the **Transactions** requests |\n| `walletAddress` | `0x1111111111111111111111111111111111111111` (illustrative, no positions) | `users.positions`, `users.transactions` |\n| `senderAddress` | `0x1111111111111111111111111111111111111111` (illustrative, holds nothing) | `transaction.build`: the wallet that signs and sends |\n| `depositAmount` | `1000000000` (1,000 USDC) | the `DEPOSIT` requests, in USDC base units (6 decimals) |\n| `redeemShares` | `250000000000000000000` (250 shares) | the `REDEEM_REQUEST` requests, in share base units (18 decimals) |\n| `historyFrom`, `historyTo` | empty (last 30 days) | `vaults.history - custom range`, Unix seconds |\n| `transactionsCursor` | set by the scripts | `users.transactions - next page` |\n\n### What the collection does for you\n\n- Sends your key as `x-partner-api-key` on every request (collection auth). The **Errors** folder overrides it on purpose.\n- Sends a new `x-request-id` on every request. Quote the id from the response when you contact Kamui.\n- Runs tests after every response: the `{ data, asOf }` or `{ error, code, requestId }` envelope, `Cache-Control: no-store`, and checks per action. See the **Test Results** tab.\n- Keeps the `users.transactions` cursor for you: send **first page**, then **next page** until it logs \"Last page\".\n- Fails one test named **rate limit not exceeded** when a request answers `429 rate_limited`, with the `Retry-After` wait and your limit. Each API client has per-minute limits: by default 120 requests for the read actions and 20 for the transaction actions. One run of the collection stays within the defaults.\n- Never signs or sends a transaction: the **Transactions** requests return unsigned transactions for your wallet stack to sign and send.\n- Each request has saved example responses, so you can see the shapes before you have a key.\n\nYou can run the whole collection with the Collection Runner: every request checks its own outcome, including the deliberate errors.\n\nPostman on the web needs the Postman Desktop Agent or the Cloud Agent, because the API sends no CORS headers (it is for server-to-server use).\n\n---\n\nAPI for Kamui vault data and for the unsigned transactions that deposit into a vault or create a redeem request on it, served by a Supabase Edge Function. The function never signs or sends a transaction: your users sign and send the transactions it builds. It writes no state apart from recording when each API key was last used.\n\n## Base URL\n\n`https://api.kamui.finance/functions/v1/external-api`\n\n## Requests\n\n- Call every action as `POST <base URL>/<action>` with a JSON object body and `Content-Type: application/json`. The body may be at most 16 KiB.\n- Bodies are strict: an unknown field is a 400, and so is a field named twice in one object (`is a duplicate field`).\n- Only POST is allowed. Any other method answers 405 `method_not_allowed`.\n- The function checks the method first, then the API key, then your rate limit, then the action. An unknown action counts against your read limit and answers 404 `route_not_found` with a valid key, and 401 without one.\n\n## Authentication\n\n- Send your API key in the `x-partner-api-key` header on every request, including `health.ping`.\n- A key looks like `kmi_<id>_<secret>`: `kmi_`, 12 lowercase base32 characters, `_`, then 43 base64url characters (60 characters in total). `kmi_<id>` is the key prefix. After creation Kamui sees only the prefix.\n- Kamui issues the keys. The full key is shown once, when it is created, so store it in a secret manager. A lost key cannot be recovered; Kamui rotates it instead.\n- Rotation issues a new key. The old key keeps working for a grace period that Kamui sets when it rotates (24 hours by default), then stops.\n- Kamui can also revoke a key at once.\n- A missing, malformed, unknown, revoked or expired key always answers the same 401 `unauthorized`.\n- Call the API from your backend only. The function sends no CORS headers, and a browser or mobile app must never hold the key.\n\n## Request ids\n\n- You may send an `x-request-id` header: 1 to 128 letters, digits, `.`, `_`, `:` or `-`. Any other value is replaced with a new UUID.\n- Every response carries the id in its `x-request-id` header, and every error body in `requestId`. Quote it when you contact Kamui.\n\n## Responses\n\n- Success: `{ \"data\": …, \"asOf\": <Unix seconds> }`.\n- Error: `{ \"error\": \"<message>\", \"code\": \"<code>\", \"requestId\": \"<id>\" }`, plus `details` (a list of `{ \"path\", \"issue\" }`) when the request is invalid. Branch on `code`; the message text may change.\n- Responses are never cached (`Cache-Control: no-store`).\n\n| HTTP | `code` | Meaning |\n| --- | --- | --- |\n| 400 | `invalid_request` | A field is missing, has the wrong type or value, or is unknown. See `details`. |\n| 400 | `invalid_amount` | The amount is above the per-request limit. See `details`. |\n| 400 | `amount_below_minimum` | The deposit is below the minimum. See `details`. |\n| 401 | `unauthorized` | The API key is missing, malformed, unknown, revoked or expired. |\n| 403 | `actions_not_enabled` | Transaction building is not enabled for your API client. Ask Kamui. |\n| 403 | `wallet_not_allowed` | The vault's allow list (`isAllowed`) does not accept the wallet. |\n| 404 | `route_not_found` | The action does not exist. |\n| 404 | `vault_not_found` | No vault has this slug. |\n| 405 | `method_not_allowed` | Use POST. |\n| 409 | `vault_not_active` | The vault exists but is not open yet. |\n| 409 | `vault_paused` | The vault is paused. |\n| 409 | `deposits_unavailable` | The vault does not accept synchronous deposits now (sync mode, or the NAV is being updated). |\n| 409 | `deposit_cap_reached` | The deposit would exceed the vault's cap. |\n| 409 | `redeem_request_already_pending` | The wallet already has a redeem request waiting for settlement in this vault. |\n| 413 | `payload_too_large` | The body is over 16 KiB. |\n| 415 | `unsupported_media_type` | Send `Content-Type: application/json`. |\n| 422 | `insufficient_balance` | The wallet holds less USDC than the deposit. |\n| 422 | `insufficient_shares` | The wallet holds fewer shares than the redeem request. |\n| 422 | `simulation_failed` | A built transaction reverts in simulation. `details` names the transaction and the error. |\n| 429 | `rate_limited` | Your client is over its per-minute limit. Wait `Retry-After` seconds. |\n| 500 | `internal_error` | Unexpected error. Retry later and quote the request id. |\n| 502 | `upstream_error` | A data source (the vault indexer or the chain) returned an error. Retry with backoff. |\n| 503 | `service_unavailable` | The service is temporarily unavailable. Retry with backoff. |\n| 503 | `actions_disabled` | Transaction building is switched off. The read actions still answer. |\n| 504 | `upstream_timeout` | A data source did not answer in time. Retry with backoff. |\n\n## Data conventions\n\n- Onchain amounts are base-unit integer strings: USDC has 6 decimals, vault shares have 18.\n- In `vaults.history`, share prices and TVL are decimal strings in the deposit asset, with its decimals (`\"1.002182\"`).\n- APY and APR values are numbers in percent (`3.55` is 3.55% a year). Fees are in basis points (`100` is 1%).\n- USD values are numbers for display. USDC counts as exactly $1.\n- Timestamps are Unix seconds, UTC.\n- Addresses are accepted in lowercase or EIP-55 and returned in EIP-55. Other mixed case, all-uppercase hex and a `0X` prefix are a 400.\n- Vault slugs: `stable-vault`, `balanced-vault`, `boosted-vault`. The legacy slugs `advanced-vault` and `aggressive-vault` are accepted; responses always carry the canonical slug. Slugs are matched exactly: case and whitespace count, so `Stable-Vault` is a 400.\n- `users.transactions` cursors are opaque and signed. Send `nextCursor` back unchanged, with the same filters; a changed cursor is a 400 `invalid_cursor`.\n- Ethereum mainnet only (`chainId` 1).\n\n## Transactions\n\n`transaction.quote` and `transaction.build` cover two transaction types, set in the body's `type`:\n\n- `DEPOSIT`: a synchronous deposit of USDC (`syncDeposit`). The shares are minted in the same transaction.\n- `REDEEM_REQUEST`: a redeem request (`requestRedeem`). The shares leave the wallet at once, and the vault settles the request later. A redeem request is the only way out of a Kamui vault.\n\nBoth take the vault's `slug` in the body, like every other action.\n\n- `transaction.quote` prices the transaction and says whether the vault takes it now (`availability`). It builds no transaction.\n- `transaction.build` runs every check in a fixed order (the first failure answers), returns the unsigned transactions and simulates them.\n- Send the transactions in `step` order from `from`, and wait for each receipt before you send the next. Each `to` is the vault or, for an approval, the deposit asset; `value` is always `\"0\"`. An approval is for the exact deposit amount, never unlimited.\n- Every read is pinned to `blockNumber`, and the simulation runs on top of it. Build again after a 409, or when more than 10 minutes have passed.\n- Once a redeem request settles, its assets are claimable. The API builds no claim: the wallet claims them in the Kamui app, or Lagoon pays them out in the wallet's next redeem request (`claimFirst`).\n- Transaction building must be enabled for your API client; until it is, both actions answer 403 `actions_not_enabled`.\n- Transaction building can be switched off. It then answers 503 `actions_disabled`, and the read actions keep answering.\n\n## Limits\n\n- Each client has per-minute request limits, shared by all of its API keys: one for the read actions and a lower one for the transaction-building actions. By default they are 120 read requests and 20 transaction requests a minute; Kamui can set other limits for your client.\n- Every request with a valid API key counts, whatever the answer: a 400, 413 or 415 counts too, and an unknown action counts against the read limit. A request without a valid key (401) or with another method (405) does not count.\n- The transaction limit is checked before transaction building's own checks, so a 429 can come before a 403 `actions_not_enabled` or a 503 `actions_disabled`.\n- The windows are fixed UTC minutes. Every counted response carries `RateLimit-Policy` (for example `\"read\";q=120;w=60`: the limit and the window in seconds), `RateLimit` (`\"read\";r=119;t=42`: the requests left and the seconds until the window resets), and `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` (Unix seconds).\n- Over the limit, the API answers 429 `rate_limited` with `Retry-After` in seconds. Wait that long before the next request.\n- If Kamui cannot check the limit for a moment, the read actions still answer (without the rate-limit headers), and the transaction actions answer 503 `service_unavailable`.\n- Avoid tight polling loops.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "version": "1.0.0"
  },
  "item": [
    {
      "id": "8cb07a08-2d31-5b39-9ab8-1e1927de51c3",
      "name": "Health",
      "description": "Check that the API is up and that your key works.",
      "item": [
        {
          "id": "98d79434-dd8f-5f78-aa51-a22d98c12166",
          "name": "health.ping",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const data = pm.response.json().data;",
                  "  pm.test(\"status ok\", () => pm.expect(data).to.eql({ status: \"ok\", service: \"external-api\" }));",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/health.ping",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "health.ping"
              ]
            },
            "description": "`POST {{baseUrl}}/health.ping`\n\nChecks that the function is up and that your API key works. Send an empty JSON object. A 200 with `status: \"ok\"` means the key was accepted.\n\n**Body:** an empty JSON object `{}`. Unknown and duplicate fields are rejected.\n\nSend this first: a `200` with `\"status\": \"ok\"` means your key works. A `401` means the key is missing or not accepted.",
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 The function is up and the key works",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/health.ping",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "health.ping"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "30880e9b-86c2-5df9-b7d9-3b5c9144c015"
                }
              ],
              "body": "{\n  \"data\": {\n    \"status\": \"ok\",\n    \"service\": \"external-api\"\n  },\n  \"asOf\": 1791454901\n}"
            },
            {
              "name": "401 The API key is missing, malformed, unknown, revoked or expired.",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/health.ping",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "health.ping"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "ea80702c-a332-4e32-922e-76bcb02e6156"
                }
              ],
              "body": "{\n  \"error\": \"Unauthorized.\",\n  \"code\": \"unauthorized\",\n  \"requestId\": \"ea80702c-a332-4e32-922e-76bcb02e6156\"\n}"
            },
            {
              "name": "429 rate_limited",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/health.ping",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "health.ping"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Too Many Requests",
              "code": 429,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "8e2f4a6c-1b3d-4e5f-9a7b-0c2d4e6f8a1b"
                },
                {
                  "key": "Retry-After",
                  "value": "18"
                },
                {
                  "key": "RateLimit-Policy",
                  "value": "\"read\";q=120;w=60"
                },
                {
                  "key": "RateLimit",
                  "value": "\"read\";r=0;t=18"
                },
                {
                  "key": "X-RateLimit-Limit",
                  "value": "120"
                },
                {
                  "key": "X-RateLimit-Remaining",
                  "value": "0"
                },
                {
                  "key": "X-RateLimit-Reset",
                  "value": "1791454980"
                }
              ],
              "body": "{\n  \"error\": \"Too many requests. Wait and try again.\",\n  \"code\": \"rate_limited\",\n  \"requestId\": \"8e2f4a6c-1b3d-4e5f-9a7b-0c2d4e6f8a1b\"\n}"
            }
          ]
        }
      ]
    },
    {
      "id": "ad7976be-5104-5e3f-987b-6a8c64abd361",
      "name": "Vaults",
      "description": "Vault data that is the same for every wallet.",
      "item": [
        {
          "id": "b2d0a1ed-4fd3-5f0e-bb13-a67ae4040f73",
          "name": "vaults.list",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const isBaseUnits = (value) => typeof value === \"string\" && /^[0-9]+$/.test(value);",
                  "  const isAddress = (value) => typeof value === \"string\" && /^0x[0-9a-fA-F]{40}$/.test(value);",
                  "",
                  "  const checkVault = (vault) => {",
                  "    pm.expect(vault.slug).to.match(/^[a-z0-9]+(-[a-z0-9]+)*$/);",
                  "    pm.expect(vault.status).to.be.oneOf([\"active\", \"coming_soon\"]);",
                  "    pm.expect(isAddress(vault.asset.address)).to.eql(true);",
                  "    pm.expect(vault.asset.decimals).to.be.a(\"number\");",
                  "    pm.expect(vault.apy.source).to.be.oneOf([\"live\", \"target\"]);",
                  "    pm.expect(vault.operations.depositsOpen).to.be.a(\"boolean\");",
                  "    if (vault.status === \"active\") {",
                  "      pm.expect(isAddress(vault.address)).to.eql(true);",
                  "      pm.expect(isBaseUnits(vault.onchain.totalAssets)).to.eql(true);",
                  "      pm.expect(isBaseUnits(vault.onchain.totalSupply)).to.eql(true);",
                  "      pm.expect(isBaseUnits(vault.onchain.sharePrice)).to.eql(true);",
                  "    } else {",
                  "      pm.expect(vault.address).to.eql(null);",
                  "      pm.expect(vault.onchain).to.eql(null);",
                  "    }",
                  "  };",
                  "  const data = pm.response.json().data;",
                  "  pm.test(\"Ethereum mainnet, read at one block\", () => {",
                  "    pm.expect(data.chainId).to.eql(1);",
                  "    pm.expect(data.blockNumber).to.be.above(0);",
                  "  });",
                  "  pm.test(\"every vault is well formed and listed once\", () => {",
                  "    pm.expect(data.vaults).to.be.an(\"array\").that.is.not.empty;",
                  "    data.vaults.forEach(checkVault);",
                  "    const slugs = data.vaults.map((vault) => vault.slug);",
                  "    pm.expect(new Set(slugs).size).to.eql(slugs.length);",
                  "  });",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/vaults.list",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "vaults.list"
              ]
            },
            "description": "`POST {{baseUrl}}/vaults.list`\n\nEvery public Kamui vault with its live state, in the order the Kamui app lists them. Send an empty JSON object.\n\n- `onchain` is read at one block (`blockNumber`): total assets and supply, the price of one share, TVL, the deposit cap, the fees, and the paused, NAV and sync-mode flags. Amounts are base-unit integer strings.\n- `apy.value` is the 30-day net APR from Lagoon (`source: \"live\"`), or the target set by Kamui (`source: \"target\"`) while the live value is unavailable. `netApr` gives the live 7-day, 30-day and since-inception values, or null when one is unavailable: `d7` is null when the vault's NAV was not updated in the last 7 days.\n- `operations.depositsOpen` is true when a synchronous deposit is accepted now. `operations.lifecycle` comes from Lagoon's indexer and can lag the chain by a few minutes. When it is null, only the onchain flags decide `depositsOpen`.\n- A coming-soon vault has no address, no `onchain` state and no live APR.\n- If Lagoon is unavailable, the request still answers: `apy` falls back to the target, and `netApr` and `lifecycle` are null.\n- If the chain read fails, the request fails (502, 503 or 504) rather than return partial state.\n\n**Body:** an empty JSON object `{}`. Unknown and duplicate fields are rejected.",
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 The three vaults on mainnet",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/vaults.list",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "vaults.list"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "2fa8b129-c2fa-5a7c-af6e-61d5188046e6"
                }
              ],
              "body": "{\n  \"data\": {\n    \"chainId\": 1,\n    \"blockNumber\": 26147329,\n    \"vaults\": [\n      {\n        \"slug\": \"stable-vault\",\n        \"name\": \"Stable Vault\",\n        \"symbol\": \"USDst\",\n        \"status\": \"active\",\n        \"address\": \"0xcDA323c2DF692d989B24BA51D0aCCa924cf9a344\",\n        \"asset\": {\n          \"address\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n          \"symbol\": \"USDC\",\n          \"decimals\": 6\n        },\n        \"apy\": {\n          \"value\": 3.5552,\n          \"source\": \"live\"\n        },\n        \"netApr\": {\n          \"d7\": 3.6482,\n          \"d30\": 3.5552,\n          \"inception\": 3.5552\n        },\n        \"onchain\": {\n          \"shareDecimals\": 18,\n          \"totalAssets\": \"2520805577613\",\n          \"totalSupply\": \"2514206304824688802868371\",\n          \"sharePrice\": \"1002624\",\n          \"tvlUsd\": 2520805.577613,\n          \"depositCap\": null,\n          \"fees\": {\n            \"managementBps\": 0,\n            \"performanceBps\": 0,\n            \"entryBps\": 0,\n            \"exitBps\": 0,\n            \"haircutBps\": 0\n          },\n          \"paused\": false,\n          \"navValid\": true,\n          \"syncMode\": \"sync_deposit\",\n          \"asyncOnly\": false\n        },\n        \"operations\": {\n          \"depositsOpen\": true,\n          \"lifecycle\": \"open\"\n        }\n      },\n      {\n        \"slug\": \"balanced-vault\",\n        \"name\": \"Balanced Vault\",\n        \"symbol\": \"USDbl\",\n        \"status\": \"active\",\n        \"address\": \"0xA5AE405242f42C47996a0C6857ff10a77F9bdeE6\",\n        \"asset\": {\n          \"address\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n          \"symbol\": \"USDC\",\n          \"decimals\": 6\n        },\n        \"apy\": {\n          \"value\": 7.456,\n          \"source\": \"live\"\n        },\n        \"netApr\": {\n          \"d7\": 7.2334,\n          \"d30\": 7.456,\n          \"inception\": 7.456\n        },\n        \"onchain\": {\n          \"shareDecimals\": 18,\n          \"totalAssets\": \"209334602655\",\n          \"totalSupply\": \"208177770987510665372408\",\n          \"sharePrice\": \"1005556\",\n          \"tvlUsd\": 209334.602655,\n          \"depositCap\": null,\n          \"fees\": {\n            \"managementBps\": 0,\n            \"performanceBps\": 0,\n            \"entryBps\": 0,\n            \"exitBps\": 0,\n            \"haircutBps\": 0\n          },\n          \"paused\": false,\n          \"navValid\": true,\n          \"syncMode\": \"sync_deposit\",\n          \"asyncOnly\": false\n        },\n        \"operations\": {\n          \"depositsOpen\": true,\n          \"lifecycle\": \"open\"\n        }\n      },\n      {\n        \"slug\": \"boosted-vault\",\n        \"name\": \"Boosted Vault\",\n        \"symbol\": \"USDbt\",\n        \"status\": \"active\",\n        \"address\": \"0x9E0DB8F43bb91e2148B0Db920E21370525CF3Aab\",\n        \"asset\": {\n          \"address\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n          \"symbol\": \"USDC\",\n          \"decimals\": 6\n        },\n        \"apy\": {\n          \"value\": 10.1855,\n          \"source\": \"live\"\n        },\n        \"netApr\": {\n          \"d7\": 9.8396,\n          \"d30\": 10.1855,\n          \"inception\": 10.1855\n        },\n        \"onchain\": {\n          \"shareDecimals\": 18,\n          \"totalAssets\": \"436234529471\",\n          \"totalSupply\": \"433355326583650535453892\",\n          \"sharePrice\": \"1006643\",\n          \"tvlUsd\": 436234.529471,\n          \"depositCap\": null,\n          \"fees\": {\n            \"managementBps\": 0,\n            \"performanceBps\": 0,\n            \"entryBps\": 0,\n            \"exitBps\": 0,\n            \"haircutBps\": 0\n          },\n          \"paused\": false,\n          \"navValid\": true,\n          \"syncMode\": \"sync_deposit\",\n          \"asyncOnly\": false\n        },\n        \"operations\": {\n          \"depositsOpen\": true,\n          \"lifecycle\": \"open\"\n        }\n      }\n    ]\n  },\n  \"asOf\": 1791458270\n}"
            }
          ]
        },
        {
          "id": "d8f752ed-961e-5d93-b3da-b545339d4104",
          "name": "vaults.get",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const isBaseUnits = (value) => typeof value === \"string\" && /^[0-9]+$/.test(value);",
                  "  const isAddress = (value) => typeof value === \"string\" && /^0x[0-9a-fA-F]{40}$/.test(value);",
                  "",
                  "  const checkVault = (vault) => {",
                  "    pm.expect(vault.slug).to.match(/^[a-z0-9]+(-[a-z0-9]+)*$/);",
                  "    pm.expect(vault.status).to.be.oneOf([\"active\", \"coming_soon\"]);",
                  "    pm.expect(isAddress(vault.asset.address)).to.eql(true);",
                  "    pm.expect(vault.asset.decimals).to.be.a(\"number\");",
                  "    pm.expect(vault.apy.source).to.be.oneOf([\"live\", \"target\"]);",
                  "    pm.expect(vault.operations.depositsOpen).to.be.a(\"boolean\");",
                  "    if (vault.status === \"active\") {",
                  "      pm.expect(isAddress(vault.address)).to.eql(true);",
                  "      pm.expect(isBaseUnits(vault.onchain.totalAssets)).to.eql(true);",
                  "      pm.expect(isBaseUnits(vault.onchain.totalSupply)).to.eql(true);",
                  "      pm.expect(isBaseUnits(vault.onchain.sharePrice)).to.eql(true);",
                  "    } else {",
                  "      pm.expect(vault.address).to.eql(null);",
                  "      pm.expect(vault.onchain).to.eql(null);",
                  "    }",
                  "  };",
                  "  const data = pm.response.json().data;",
                  "  pm.test(\"answers with the canonical slug\", () => pm.expect(data.vault.slug).to.eql(pm.variables.get(\"vaultSlug\")));",
                  "  pm.test(\"vault is well formed\", () => checkVault(data.vault));",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/vaults.get",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "vaults.get"
              ]
            },
            "description": "`POST {{baseUrl}}/vaults.get`\n\nOne vault, read the same way as `vaults.list`.\n\n- A legacy slug resolves to its canonical vault, and the response carries the canonical slug.\n- An unknown slug answers 404 `vault_not_found`. A coming-soon vault answers 200 with `status: \"coming_soon\"` and no onchain state.\n\n**Body fields** (unknown and duplicate fields are rejected)\n\n| Field | Required | Type |\n| --- | --- | --- |\n| `slug` | yes | string, pattern `^[a-z0-9]+(?:-[a-z0-9]+)*$` |",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"slug\": \"{{vaultSlug}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 One vault",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/vaults.get",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "vaults.get"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"slug\": \"{{vaultSlug}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "5e3c5d8e-547c-5841-a8ea-9b4756087ecd"
                }
              ],
              "body": "{\n  \"data\": {\n    \"chainId\": 1,\n    \"blockNumber\": 26147329,\n    \"vault\": {\n      \"slug\": \"stable-vault\",\n      \"name\": \"Stable Vault\",\n      \"symbol\": \"USDst\",\n      \"status\": \"active\",\n      \"address\": \"0xcDA323c2DF692d989B24BA51D0aCCa924cf9a344\",\n      \"asset\": {\n        \"address\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n        \"symbol\": \"USDC\",\n        \"decimals\": 6\n      },\n      \"apy\": {\n        \"value\": 3.5552,\n        \"source\": \"live\"\n      },\n      \"netApr\": {\n        \"d7\": 3.6482,\n        \"d30\": 3.5552,\n        \"inception\": 3.5552\n      },\n      \"onchain\": {\n        \"shareDecimals\": 18,\n        \"totalAssets\": \"2520805577613\",\n        \"totalSupply\": \"2514206304824688802868371\",\n        \"sharePrice\": \"1002624\",\n        \"tvlUsd\": 2520805.577613,\n        \"depositCap\": null,\n        \"fees\": {\n          \"managementBps\": 0,\n          \"performanceBps\": 0,\n          \"entryBps\": 0,\n          \"exitBps\": 0,\n          \"haircutBps\": 0\n        },\n        \"paused\": false,\n        \"navValid\": true,\n        \"syncMode\": \"sync_deposit\",\n        \"asyncOnly\": false\n      },\n      \"operations\": {\n        \"depositsOpen\": true,\n        \"lifecycle\": \"open\"\n      }\n    }\n  },\n  \"asOf\": 1791458270\n}"
            },
            {
              "name": "404 No vault has this slug.",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/vaults.get",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "vaults.get"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"slug\": \"unknown-vault\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "3e515e1a-ad93-4506-81fc-aa47575c15f6"
                }
              ],
              "body": "{\n  \"error\": \"No vault exists with this slug.\",\n  \"code\": \"vault_not_found\",\n  \"requestId\": \"3e515e1a-ad93-4506-81fc-aa47575c15f6\"\n}"
            }
          ]
        },
        {
          "id": "7f90fa95-10ec-5c58-9d03-a37ddb61e716",
          "name": "vaults.get - legacy slug",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const isBaseUnits = (value) => typeof value === \"string\" && /^[0-9]+$/.test(value);",
                  "  const isAddress = (value) => typeof value === \"string\" && /^0x[0-9a-fA-F]{40}$/.test(value);",
                  "",
                  "  const checkVault = (vault) => {",
                  "    pm.expect(vault.slug).to.match(/^[a-z0-9]+(-[a-z0-9]+)*$/);",
                  "    pm.expect(vault.status).to.be.oneOf([\"active\", \"coming_soon\"]);",
                  "    pm.expect(isAddress(vault.asset.address)).to.eql(true);",
                  "    pm.expect(vault.asset.decimals).to.be.a(\"number\");",
                  "    pm.expect(vault.apy.source).to.be.oneOf([\"live\", \"target\"]);",
                  "    pm.expect(vault.operations.depositsOpen).to.be.a(\"boolean\");",
                  "    if (vault.status === \"active\") {",
                  "      pm.expect(isAddress(vault.address)).to.eql(true);",
                  "      pm.expect(isBaseUnits(vault.onchain.totalAssets)).to.eql(true);",
                  "      pm.expect(isBaseUnits(vault.onchain.totalSupply)).to.eql(true);",
                  "      pm.expect(isBaseUnits(vault.onchain.sharePrice)).to.eql(true);",
                  "    } else {",
                  "      pm.expect(vault.address).to.eql(null);",
                  "      pm.expect(vault.onchain).to.eql(null);",
                  "    }",
                  "  };",
                  "  const data = pm.response.json().data;",
                  "  pm.test(\"answers with the canonical slug\", () => pm.expect(data.vault.slug).to.eql(\"boosted-vault\"));",
                  "  pm.test(\"vault is well formed\", () => checkVault(data.vault));",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/vaults.get",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "vaults.get"
              ]
            },
            "description": "Legacy slug: aggressive-vault resolves to boosted-vault. See the first `vaults.get` request for the fields and the full description.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"slug\": \"aggressive-vault\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 A legacy slug answers with the canonical slug",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/vaults.get",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "vaults.get"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"slug\": \"aggressive-vault\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "9625b084-9083-505b-937d-15a386dd6a44"
                }
              ],
              "body": "{\n  \"data\": {\n    \"chainId\": 1,\n    \"blockNumber\": 26147329,\n    \"vault\": {\n      \"slug\": \"boosted-vault\",\n      \"name\": \"Boosted Vault\",\n      \"symbol\": \"USDbt\",\n      \"status\": \"active\",\n      \"address\": \"0x9E0DB8F43bb91e2148B0Db920E21370525CF3Aab\",\n      \"asset\": {\n        \"address\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n        \"symbol\": \"USDC\",\n        \"decimals\": 6\n      },\n      \"apy\": {\n        \"value\": 10.1855,\n        \"source\": \"live\"\n      },\n      \"netApr\": {\n        \"d7\": 9.8396,\n        \"d30\": 10.1855,\n        \"inception\": 10.1855\n      },\n      \"onchain\": {\n        \"shareDecimals\": 18,\n        \"totalAssets\": \"436234529471\",\n        \"totalSupply\": \"433355326583650535453892\",\n        \"sharePrice\": \"1006643\",\n        \"tvlUsd\": 436234.529471,\n        \"depositCap\": null,\n        \"fees\": {\n          \"managementBps\": 0,\n          \"performanceBps\": 0,\n          \"entryBps\": 0,\n          \"exitBps\": 0,\n          \"haircutBps\": 0\n        },\n        \"paused\": false,\n        \"navValid\": true,\n        \"syncMode\": \"sync_deposit\",\n        \"asyncOnly\": false\n      },\n      \"operations\": {\n        \"depositsOpen\": true,\n        \"lifecycle\": \"open\"\n      }\n    }\n  },\n  \"asOf\": 1791458270\n}"
            }
          ]
        },
        {
          "id": "6ca26330-13a7-5b68-991c-e444871ac55f",
          "name": "vaults.history - share price",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const result = pm.response.json().data;",
                  "  pm.test(\"canonical slug and metric echoed\", () => {",
                  "    pm.expect(result.slug).to.eql(pm.variables.get(\"vaultSlug\"));",
                  "    pm.expect(result.metric).to.eql(\"share_price\");",
                  "    pm.expect(result.unit).to.be.a(\"string\");",
                  "    pm.expect(result.from).to.be.below(result.to);",
                  "  });",
                  "  pm.test(\"points ascend, start a UTC day and are decimal strings\", () => {",
                  "    let previous = -Infinity;",
                  "    for (const point of result.points) {",
                  "      pm.expect(point.t % 86400).to.eql(0);",
                  "      pm.expect(point.t).to.be.above(previous);",
                  "      pm.expect(point.v).to.match(/^[0-9]+\\.[0-9]+$/);",
                  "      previous = point.t;",
                  "    }",
                  "  });",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/vaults.history",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "vaults.history"
              ]
            },
            "description": "`POST {{baseUrl}}/vaults.history`\n\nShare price (`metric: \"share_price\"`) or TVL (`metric: \"tvl\"`) history of one vault, in its deposit asset.\n\n- Each point is the last value recorded on a UTC day: `t` is the day's start in Unix seconds and `v` the value as a decimal string. Days without a change have no point. Points are in ascending order.\n- `to` defaults to now and `from` to 90 days before `to`. `from` must be before `to`, and the range may be at most 366 days.\n- Timestamps before 2024-01-01 or more than one day in the future are rejected.\n- A legacy slug resolves to its canonical vault, and the response carries the canonical slug.\n\n**Body fields** (unknown and duplicate fields are rejected)\n\n| Field | Required | Type |\n| --- | --- | --- |\n| `slug` | yes | string, pattern `^[a-z0-9]+(?:-[a-z0-9]+)*$` |\n| `metric` | yes | string (one of `share_price`, `tvl`) |\n| `from` | no | integer, ≥ 1704067200 |\n| `to` | no | integer, ≥ 1704067200 |",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"slug\": \"{{vaultSlug}}\",\n  \"metric\": \"share_price\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 Share price (points trimmed)",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/vaults.history",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "vaults.history"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"slug\": \"{{vaultSlug}}\",\n  \"metric\": \"share_price\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "9903e851-5ade-57d7-90c6-216be1d750ef"
                }
              ],
              "body": "{\n  \"data\": {\n    \"slug\": \"stable-vault\",\n    \"metric\": \"share_price\",\n    \"unit\": \"USDC\",\n    \"from\": 1783678901,\n    \"to\": 1791454901,\n    \"points\": [\n      {\n        \"t\": 1788048000,\n        \"v\": \"1.000000\"\n      },\n      {\n        \"t\": 1788825600,\n        \"v\": \"0.999999\"\n      },\n      {\n        \"t\": 1789084800,\n        \"v\": \"1.000000\"\n      },\n      {\n        \"t\": 1791244800,\n        \"v\": \"1.002024\"\n      },\n      {\n        \"t\": 1791331200,\n        \"v\": \"1.002103\"\n      },\n      {\n        \"t\": 1791417600,\n        \"v\": \"1.002182\"\n      }\n    ]\n  },\n  \"asOf\": 1791454901\n}"
            },
            {
              "name": "404 No vault has this slug.",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/vaults.history",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "vaults.history"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"slug\": \"unknown-vault\",\n  \"metric\": \"share_price\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "3e515e1a-ad93-4506-81fc-aa47575c15f6"
                }
              ],
              "body": "{\n  \"error\": \"No vault exists with this slug.\",\n  \"code\": \"vault_not_found\",\n  \"requestId\": \"3e515e1a-ad93-4506-81fc-aa47575c15f6\"\n}"
            },
            {
              "name": "409 The vault exists but is not open yet.",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/vaults.history",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "vaults.history"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"slug\": \"{{vaultSlug}}\",\n  \"metric\": \"share_price\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Conflict",
              "code": 409,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "6f1d2c3b-8a47-4e59-b0c6-2d9e4f7a1b85"
                }
              ],
              "body": "{\n  \"error\": \"This vault is not open yet.\",\n  \"code\": \"vault_not_active\",\n  \"requestId\": \"6f1d2c3b-8a47-4e59-b0c6-2d9e4f7a1b85\"\n}"
            }
          ]
        },
        {
          "id": "c8a1692a-46d6-5eaa-8122-810c58c5993b",
          "name": "vaults.history - TVL",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const result = pm.response.json().data;",
                  "  pm.test(\"canonical slug and metric echoed\", () => {",
                  "    pm.expect(result.slug).to.eql(pm.variables.get(\"vaultSlug\"));",
                  "    pm.expect(result.metric).to.eql(\"tvl\");",
                  "    pm.expect(result.unit).to.be.a(\"string\");",
                  "    pm.expect(result.from).to.be.below(result.to);",
                  "  });",
                  "  pm.test(\"points ascend, start a UTC day and are decimal strings\", () => {",
                  "    let previous = -Infinity;",
                  "    for (const point of result.points) {",
                  "      pm.expect(point.t % 86400).to.eql(0);",
                  "      pm.expect(point.t).to.be.above(previous);",
                  "      pm.expect(point.v).to.match(/^[0-9]+\\.[0-9]+$/);",
                  "      previous = point.t;",
                  "    }",
                  "  });",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/vaults.history",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "vaults.history"
              ]
            },
            "description": "TVL, last 90 days (default range). See the first `vaults.history` request for the fields and the full description.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"slug\": \"{{vaultSlug}}\",\n  \"metric\": \"tvl\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 TVL (points trimmed)",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/vaults.history",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "vaults.history"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"slug\": \"{{vaultSlug}}\",\n  \"metric\": \"tvl\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "8c680720-6153-5550-b3cd-356c3e4ae1b1"
                }
              ],
              "body": "{\n  \"data\": {\n    \"slug\": \"stable-vault\",\n    \"metric\": \"tvl\",\n    \"unit\": \"USDC\",\n    \"from\": 1783678901,\n    \"to\": 1791454901,\n    \"points\": [\n      {\n        \"t\": 1788048000,\n        \"v\": \"0.000000\"\n      },\n      {\n        \"t\": 1788480000,\n        \"v\": \"100.000000\"\n      },\n      {\n        \"t\": 1788652800,\n        \"v\": \"80.000000\"\n      },\n      {\n        \"t\": 1791417600,\n        \"v\": \"250180.420000\"\n      }\n    ]\n  },\n  \"asOf\": 1791454901\n}"
            }
          ]
        },
        {
          "id": "f46d52da-0e9d-5bb6-be2d-c44a8bcb6f18",
          "name": "vaults.history - custom range",
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "// When historyFrom / historyTo are empty, ask for the last 30 full UTC days.",
                  "const day = 86400;",
                  "const today = Math.floor(Date.now() / 1000 / day) * day;",
                  "if (!pm.variables.get(\"historyTo\")) pm.variables.set(\"historyTo\", String(today));",
                  "if (!pm.variables.get(\"historyFrom\")) pm.variables.set(\"historyFrom\", String(Number(pm.variables.get(\"historyTo\")) - 30 * day));"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const result = pm.response.json().data;",
                  "  pm.test(\"canonical slug and metric echoed\", () => {",
                  "    pm.expect(result.slug).to.eql(pm.variables.get(\"vaultSlug\"));",
                  "    pm.expect(result.metric).to.eql(\"share_price\");",
                  "    pm.expect(result.unit).to.be.a(\"string\");",
                  "    pm.expect(result.from).to.be.below(result.to);",
                  "  });",
                  "  pm.test(\"points ascend, start a UTC day and are decimal strings\", () => {",
                  "    let previous = -Infinity;",
                  "    for (const point of result.points) {",
                  "      pm.expect(point.t % 86400).to.eql(0);",
                  "      pm.expect(point.t).to.be.above(previous);",
                  "      pm.expect(point.v).to.match(/^[0-9]+\\.[0-9]+$/);",
                  "      previous = point.t;",
                  "    }",
                  "  });",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/vaults.history",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "vaults.history"
              ]
            },
            "description": "Share price for a custom range (Unix seconds). See the first `vaults.history` request for the fields and the full description.\n\nSet `historyFrom` and `historyTo` (Unix seconds) in the variables. When they are empty, the pre-request script asks for the last 30 full UTC days.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"slug\": \"{{vaultSlug}}\",\n  \"metric\": \"share_price\",\n  \"from\": {{historyFrom}},\n  \"to\": {{historyTo}}\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "id": "f4629d4d-3de1-51b3-9a09-b302b85b935b",
          "name": "vaults.history - legacy slug",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const result = pm.response.json().data;",
                  "  pm.test(\"canonical slug and metric echoed\", () => {",
                  "    pm.expect(result.slug).to.eql(\"boosted-vault\");",
                  "    pm.expect(result.metric).to.eql(\"share_price\");",
                  "    pm.expect(result.unit).to.be.a(\"string\");",
                  "    pm.expect(result.from).to.be.below(result.to);",
                  "  });",
                  "  pm.test(\"points ascend, start a UTC day and are decimal strings\", () => {",
                  "    let previous = -Infinity;",
                  "    for (const point of result.points) {",
                  "      pm.expect(point.t % 86400).to.eql(0);",
                  "      pm.expect(point.t).to.be.above(previous);",
                  "      pm.expect(point.v).to.match(/^[0-9]+\\.[0-9]+$/);",
                  "      previous = point.t;",
                  "    }",
                  "  });",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/vaults.history",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "vaults.history"
              ]
            },
            "description": "Legacy slug: aggressive-vault resolves to boosted-vault. See the first `vaults.history` request for the fields and the full description.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"slug\": \"aggressive-vault\",\n  \"metric\": \"share_price\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 A legacy slug answers with the canonical slug (points trimmed)",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/vaults.history",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "vaults.history"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"slug\": \"aggressive-vault\",\n  \"metric\": \"share_price\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "5717a74e-5032-5310-8bfb-050a2895d226"
                }
              ],
              "body": "{\n  \"data\": {\n    \"slug\": \"boosted-vault\",\n    \"metric\": \"share_price\",\n    \"unit\": \"USDC\",\n    \"from\": 1783678901,\n    \"to\": 1791454901,\n    \"points\": [\n      {\n        \"t\": 1791331200,\n        \"v\": \"1.002103\"\n      },\n      {\n        \"t\": 1791417600,\n        \"v\": \"1.002182\"\n      }\n    ]\n  },\n  \"asOf\": 1791454901\n}"
            }
          ]
        }
      ]
    },
    {
      "id": "7d197333-d4eb-5a73-9112-47235243fa14",
      "name": "Users",
      "description": "Data about one wallet.",
      "item": [
        {
          "id": "8ac61f6d-0fb1-541f-a3ca-5d6af428004f",
          "name": "users.positions",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const isBaseUnits = (value) => typeof value === \"string\" && /^[0-9]+$/.test(value);",
                  "  const isAddress = (value) => typeof value === \"string\" && /^0x[0-9a-fA-F]{40}$/.test(value);",
                  "  const data = pm.response.json().data;",
                  "  pm.test(\"the wallet is echoed in EIP-55, on mainnet, at one block\", () => {",
                  "    pm.expect(data.address.toLowerCase()).to.eql(pm.variables.get(\"walletAddress\").toLowerCase());",
                  "    pm.expect(data.chainId).to.eql(1);",
                  "    pm.expect(data.blockNumber).to.be.above(0);",
                  "  });",
                  "  pm.test(\"totals are USD numbers\", () => {",
                  "    for (const key of [\"valueUsd\", \"pendingDepositsUsd\", \"claimableDepositsUsd\", \"pendingRedemptionsUsd\", \"claimableRedemptionsUsd\"]) {",
                  "      pm.expect(data.totals[key]).to.be.a(\"number\");",
                  "    }",
                  "  });",
                  "  pm.test(\"amounts are base-unit integer strings\", () => {",
                  "    for (const position of data.positions) {",
                  "      pm.expect(isAddress(position.vault.address)).to.eql(true);",
                  "      pm.expect(isBaseUnits(position.shares)).to.eql(true);",
                  "      pm.expect(isBaseUnits(position.valueAssets)).to.eql(true);",
                  "      pm.expect(isBaseUnits(position.pendingDeposit.assets)).to.eql(true);",
                  "      pm.expect(isBaseUnits(position.pendingRedeem.shares)).to.eql(true);",
                  "      pm.expect(isBaseUnits(position.claimableRedeem.assets)).to.eql(true);",
                  "    }",
                  "  });",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/users.positions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "users.positions"
              ]
            },
            "description": "`POST {{baseUrl}}/users.positions`\n\nPositions of one wallet in every active vault, read at one block (`blockNumber`).\n\n- Each amount sits in exactly one bucket: held shares (`shares`, `valueAssets`), a deposit waiting for settlement (`pendingDeposit`), a settled deposit whose shares are not claimed yet (`claimableDeposit`), a redeem request waiting for settlement (`pendingRedeem`, estimated at the current share price), and a settled redeem request ready to claim (`claimableRedeem`).\n- `totals` sums the buckets over all vaults in USD.\n- Vaults where the wallet holds less than $0.01 and has nothing in flight are left out, so a wallet with no position answers an empty `positions` list.\n- The response contains no onboarding, consent or contact data.\n\n**Body fields** (unknown and duplicate fields are rejected)\n\n| Field | Required | Type |\n| --- | --- | --- |\n| `address` | yes | string, 42 characters, pattern `^0x[0-9a-fA-F]{40}$` |\n\nSet `walletAddress` in the variables to the wallet you want to read.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"address\": \"{{walletAddress}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 Illustrative wallet and amounts",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/users.positions",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "users.positions"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"address\": \"{{walletAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "70a32f7e-3ff2-5636-9d14-a0f7e1be8dc7"
                }
              ],
              "body": "{\n  \"data\": {\n    \"address\": \"0x1111111111111111111111111111111111111111\",\n    \"chainId\": 1,\n    \"blockNumber\": 26124800,\n    \"totals\": {\n      \"valueUsd\": 1002.182,\n      \"pendingDepositsUsd\": 0,\n      \"claimableDepositsUsd\": 0,\n      \"pendingRedemptionsUsd\": 250.5455,\n      \"claimableRedemptionsUsd\": 0\n    },\n    \"positions\": [\n      {\n        \"vault\": {\n          \"slug\": \"balanced-vault\",\n          \"address\": \"0xA5AE405242f42C47996a0C6857ff10a77F9bdeE6\"\n        },\n        \"shares\": \"1000000000000000000000\",\n        \"valueAssets\": \"1002182000\",\n        \"valueUsd\": 1002.182,\n        \"pendingDeposit\": {\n          \"assets\": \"0\"\n        },\n        \"claimableDeposit\": {\n          \"assets\": \"0\",\n          \"shares\": \"0\",\n          \"valueAssets\": \"0\"\n        },\n        \"pendingRedeem\": {\n          \"shares\": \"0\",\n          \"estimatedAssets\": \"0\"\n        },\n        \"claimableRedeem\": {\n          \"shares\": \"0\",\n          \"assets\": \"0\"\n        }\n      },\n      {\n        \"vault\": {\n          \"slug\": \"stable-vault\",\n          \"address\": \"0xcDA323c2DF692d989B24BA51D0aCCa924cf9a344\"\n        },\n        \"shares\": \"0\",\n        \"valueAssets\": \"0\",\n        \"valueUsd\": 0,\n        \"pendingDeposit\": {\n          \"assets\": \"0\"\n        },\n        \"claimableDeposit\": {\n          \"assets\": \"0\",\n          \"shares\": \"0\",\n          \"valueAssets\": \"0\"\n        },\n        \"pendingRedeem\": {\n          \"shares\": \"250000000000000000000\",\n          \"estimatedAssets\": \"250545500\"\n        },\n        \"claimableRedeem\": {\n          \"shares\": \"0\",\n          \"assets\": \"0\"\n        }\n      }\n    ]\n  },\n  \"asOf\": 1791454901\n}"
            }
          ]
        },
        {
          "id": "4ed06e5d-4a55-5f0b-b67d-3dd6967848cb",
          "name": "users.transactions - first page",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const isBaseUnits = (value) => typeof value === \"string\" && /^[0-9]+$/.test(value);",
                  "  const isAddress = (value) => typeof value === \"string\" && /^0x[0-9a-fA-F]{40}$/.test(value);",
                  "",
                  "  const data = pm.response.json().data;",
                  "  pm.test(\"rows are newest first, with base-unit amounts\", () => {",
                  "    pm.expect(data.items).to.be.an(\"array\");",
                  "    let previous = Infinity;",
                  "    for (const item of data.items) {",
                  "      pm.expect(item.timestamp).to.be.at.most(previous);",
                  "      pm.expect(item.timestamp).to.be.at.most(data.snapshotAt);",
                  "      pm.expect(item.status).to.be.oneOf([\"pending\", \"awaiting_shares\", \"claimable\", \"completed\", \"canceled\"]);",
                  "      if (item.assets !== null) pm.expect(isBaseUnits(item.assets)).to.eql(true);",
                  "      if (item.shares !== null) pm.expect(isBaseUnits(item.shares)).to.eql(true);",
                  "      previous = item.timestamp;",
                  "    }",
                  "  });",
                  "  pm.test(\"nextCursor is a string or null\", () => pm.expect(data.nextCursor === null || typeof data.nextCursor === \"string\").to.eql(true));",
                  "  pm.collectionVariables.set(\"transactionsSnapshotAt\", String(data.snapshotAt));",
                  "  // Keep the cursor for \"users.transactions - next page\".",
                  "  if (data.nextCursor) {",
                  "    pm.collectionVariables.set(\"transactionsCursor\", data.nextCursor);",
                  "    console.log(\"More rows: send \\\"users.transactions - next page\\\".\");",
                  "  } else {",
                  "    pm.collectionVariables.set(\"transactionsCursor\", \"\");",
                  "    console.log(\"Last page: nextCursor is null.\");",
                  "  }",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/users.transactions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "users.transactions"
              ]
            },
            "description": "`POST {{baseUrl}}/users.transactions`\n\nTransaction history of one wallet in every active vault, or in one vault with `slug`, with the request statuses the Kamui app shows.\n\n- Rows are newest first: by timestamp, then log index (higher first), then transaction hash (higher first). `types` keeps only the listed types.\n- Amounts are integer strings in base units: `assets` in the deposit asset (USDC, 6 decimals), `shares` in vault shares (18 decimals). A field the event does not carry is null.\n- A request row is `pending` until settled, then `awaiting_shares` (deposit) or `claimable` (redeem request) until claimed, then `completed`. A canceled request and its cancel row are `canceled`. Every other row is `completed`.\n- Paging: send `nextCursor` back as `cursor`, with the same `address`, `slug` and `types`. Stop when `nextCursor` is null. A page can hold fewer rows than `limit`, even none. A cursor that does not decode, or that comes from other filters, answers 400 `invalid_cursor`.\n- The rows of one cursor chain stop at `snapshotAt`, so an event indexed late never repeats or shifts a row. Request statuses read the chain at `blockNumber`, the latest block when the page is read, so a status can change between pages.\n- A wallet with more than 1,000 request, cancel and claim rows, or more than 1,000 rows at one timestamp, answers 503 `history_unavailable`. Any data source failure answers the same 503, never a partial page.\n- A legacy slug resolves to its canonical vault, and rows carry the canonical slug.\n\n**Body fields** (unknown and duplicate fields are rejected)\n\n| Field | Required | Type |\n| --- | --- | --- |\n| `address` | yes | string, 42 characters, pattern `^0x[0-9a-fA-F]{40}$` |\n| `slug` | no | string, pattern `^[a-z0-9]+(?:-[a-z0-9]+)*$` |\n| `types` | no | array of string (one of `DEPOSIT`, `DEPOSIT_REQUEST`, `DEPOSIT_CLAIM`, `DEPOSIT_CANCEL`, `REDEEM_REQUEST`, `REDEEM_CANCEL`, `WITHDRAW`, `WITHDRAW_INSTANT`), 1 to 8 items |\n| `limit` | no | integer, 1 to 100 |\n| `cursor` | no | string, pattern `^[A-Za-z0-9_-]+$` |\n\n**In Postman:** this request saves `nextCursor` into the `transactionsCursor` variable. Then send **users.transactions - next page** until it logs \"Last page\".",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"address\": \"{{walletAddress}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 Illustrative wallet, amounts and hashes (rows trimmed)",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/users.transactions",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "users.transactions"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"address\": \"{{walletAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "0394c72d-fe09-5ff7-bffb-1f55e1ed8fb3"
                }
              ],
              "body": "{\n  \"data\": {\n    \"address\": \"0x1111111111111111111111111111111111111111\",\n    \"chainId\": 1,\n    \"snapshotAt\": 1791454800,\n    \"blockNumber\": 26124800,\n    \"items\": [\n      {\n        \"id\": \"0x1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a-214\",\n        \"type\": \"REDEEM_REQUEST\",\n        \"status\": \"claimable\",\n        \"vault\": {\n          \"slug\": \"stable-vault\",\n          \"address\": \"0xcDA323c2DF692d989B24BA51D0aCCa924cf9a344\"\n        },\n        \"timestamp\": 1791331200,\n        \"transactionHash\": \"0x1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a\",\n        \"logIndex\": 214,\n        \"requestId\": \"41\",\n        \"assets\": null,\n        \"shares\": \"250000000000000000000\"\n      },\n      {\n        \"id\": \"0x2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b-33\",\n        \"type\": \"DEPOSIT\",\n        \"status\": \"completed\",\n        \"vault\": {\n          \"slug\": \"balanced-vault\",\n          \"address\": \"0xA5AE405242f42C47996a0C6857ff10a77F9bdeE6\"\n        },\n        \"timestamp\": 1791158400,\n        \"transactionHash\": \"0x2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b\",\n        \"logIndex\": 33,\n        \"requestId\": null,\n        \"assets\": \"1000000000\",\n        \"shares\": \"997820000000000000000\"\n      },\n      {\n        \"id\": \"0x3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c-87\",\n        \"type\": \"WITHDRAW\",\n        \"status\": \"completed\",\n        \"vault\": {\n          \"slug\": \"stable-vault\",\n          \"address\": \"0xcDA323c2DF692d989B24BA51D0aCCa924cf9a344\"\n        },\n        \"timestamp\": 1790985600,\n        \"transactionHash\": \"0x3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c\",\n        \"logIndex\": 87,\n        \"requestId\": null,\n        \"assets\": \"150300000\",\n        \"shares\": \"150000000000000000000\"\n      }\n    ],\n    \"nextCursor\": \"eyJ2IjozLCJhc09mIjoxNzkxNDU0ODAwLCJ0cyI6MTc5MDk4NTYwMCwibG9nIjo4NywidHgiOiIweDNjM2MzYzNjM2MzYzNjM2MzYzNjM2MzYzNjM2MzYzNjM2MzYzNjM2MzYzNjM2MzYzNjM2MzYzNjM2MzYzNjM2MiLCJtYWMiOiIxNmNkMGQxNTNjY2ExMWZjODIzNmZhMzNiNzhjNjdjYSJ9\"\n  },\n  \"asOf\": 1791454901\n}"
            },
            {
              "name": "200 A wallet with no history",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/users.transactions",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "users.transactions"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"address\": \"{{walletAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "d15bd9b0-bf92-5e53-836b-ab9f98231c7a"
                }
              ],
              "body": "{\n  \"data\": {\n    \"address\": \"0x1111111111111111111111111111111111111111\",\n    \"chainId\": 1,\n    \"snapshotAt\": 1791454800,\n    \"blockNumber\": null,\n    \"items\": [],\n    \"nextCursor\": null\n  },\n  \"asOf\": 1791454901\n}"
            },
            {
              "name": "503 Transaction history is unavailable. Either a data source fai...",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/users.transactions",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "users.transactions"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"address\": \"{{walletAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Service Unavailable",
              "code": 503,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "cfc8206a-76f3-4ff5-8df4-8a3f46b83035"
                }
              ],
              "body": "{\n  \"error\": \"Transaction history is temporarily unavailable.\",\n  \"code\": \"history_unavailable\",\n  \"requestId\": \"cfc8206a-76f3-4ff5-8df4-8a3f46b83035\"\n}"
            }
          ]
        },
        {
          "id": "b86d82c1-e842-5dca-94f1-53be61c9638c",
          "name": "users.transactions - next page",
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "// Pages need the nextCursor of the previous page. Send \"users.transactions - first page\" first.",
                  "if (!pm.variables.get(\"transactionsCursor\")) {",
                  "  console.log(\"No cursor: send \\\"users.transactions - first page\\\" first, or the last page was reached.\");",
                  "  pm.execution.skipRequest();",
                  "}"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const isBaseUnits = (value) => typeof value === \"string\" && /^[0-9]+$/.test(value);",
                  "  const isAddress = (value) => typeof value === \"string\" && /^0x[0-9a-fA-F]{40}$/.test(value);",
                  "",
                  "  const data = pm.response.json().data;",
                  "  pm.test(\"rows are newest first, with base-unit amounts\", () => {",
                  "    pm.expect(data.items).to.be.an(\"array\");",
                  "    let previous = Infinity;",
                  "    for (const item of data.items) {",
                  "      pm.expect(item.timestamp).to.be.at.most(previous);",
                  "      pm.expect(item.timestamp).to.be.at.most(data.snapshotAt);",
                  "      pm.expect(item.status).to.be.oneOf([\"pending\", \"awaiting_shares\", \"claimable\", \"completed\", \"canceled\"]);",
                  "      if (item.assets !== null) pm.expect(isBaseUnits(item.assets)).to.eql(true);",
                  "      if (item.shares !== null) pm.expect(isBaseUnits(item.shares)).to.eql(true);",
                  "      previous = item.timestamp;",
                  "    }",
                  "  });",
                  "  pm.test(\"nextCursor is a string or null\", () => pm.expect(data.nextCursor === null || typeof data.nextCursor === \"string\").to.eql(true));",
                  "  pm.test(\"snapshotAt stays fixed across pages\", () => pm.expect(String(data.snapshotAt)).to.eql(pm.collectionVariables.get(\"transactionsSnapshotAt\")));",
                  "  // Keep the cursor for \"users.transactions - next page\".",
                  "  if (data.nextCursor) {",
                  "    pm.collectionVariables.set(\"transactionsCursor\", data.nextCursor);",
                  "    console.log(\"More rows: send \\\"users.transactions - next page\\\".\");",
                  "  } else {",
                  "    pm.collectionVariables.set(\"transactionsCursor\", \"\");",
                  "    console.log(\"Last page: nextCursor is null.\");",
                  "  }",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/users.transactions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "users.transactions"
              ]
            },
            "description": "Next page: the previous nextCursor with the same filters. See the first `users.transactions` request for the fields and the full description.\n\nUses the `transactionsCursor` saved by **users.transactions - first page** (and by this request). Keep the same `address`, `slug` and `types` as the first page; `limit` may change. The request is skipped when there is no cursor.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"address\": \"{{walletAddress}}\",\n  \"cursor\": \"{{transactionsCursor}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "id": "5d6dc2e6-28f4-52e4-8359-93da5b6ed8d3",
          "name": "users.transactions - one vault, some types",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const isBaseUnits = (value) => typeof value === \"string\" && /^[0-9]+$/.test(value);",
                  "  const isAddress = (value) => typeof value === \"string\" && /^0x[0-9a-fA-F]{40}$/.test(value);",
                  "",
                  "  const data = pm.response.json().data;",
                  "  pm.test(\"rows are newest first, with base-unit amounts\", () => {",
                  "    pm.expect(data.items).to.be.an(\"array\");",
                  "    let previous = Infinity;",
                  "    for (const item of data.items) {",
                  "      pm.expect(item.timestamp).to.be.at.most(previous);",
                  "      pm.expect(item.timestamp).to.be.at.most(data.snapshotAt);",
                  "      pm.expect(item.status).to.be.oneOf([\"pending\", \"awaiting_shares\", \"claimable\", \"completed\", \"canceled\"]);",
                  "      if (item.assets !== null) pm.expect(isBaseUnits(item.assets)).to.eql(true);",
                  "      if (item.shares !== null) pm.expect(isBaseUnits(item.shares)).to.eql(true);",
                  "      previous = item.timestamp;",
                  "    }",
                  "  });",
                  "  pm.test(\"nextCursor is a string or null\", () => pm.expect(data.nextCursor === null || typeof data.nextCursor === \"string\").to.eql(true));",
                  "  pm.test(\"only the requested vault and types\", () => {",
                  "    for (const item of data.items) {",
                  "      pm.expect(item.vault.slug).to.eql(pm.variables.get(\"vaultSlug\"));",
                  "      pm.expect(item.type).to.be.oneOf([\"REDEEM_REQUEST\", \"WITHDRAW\"]);",
                  "    }",
                  "  });",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/users.transactions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "users.transactions"
              ]
            },
            "description": "One vault, some types, 20 rows per page. See the first `users.transactions` request for the fields and the full description.\n\nA cursor from this request only works with the same `slug` and `types`.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"address\": \"{{walletAddress}}\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"types\": [\n    \"REDEEM_REQUEST\",\n    \"WITHDRAW\"\n  ],\n  \"limit\": 20\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "id": "cf5a57cb-a923-5f95-9a4e-aab2114f2f96",
      "name": "Transactions",
      "description": "Quotes and unsigned transactions that deposit into a vault or create a redeem request on it, and the checks behind them.\n\nNothing is signed or sent: sign and send the built transactions in `step` order with your wallet stack. Transaction building must be enabled for your API client: until Kamui enables it, these requests answer `403 actions_not_enabled`. Kamui can also switch transaction building off for every client: they then answer `503 actions_disabled`, and the read actions keep answering.\n\nSet `senderAddress` to a wallet that holds USDC (for a deposit) or vault shares (for a redeem request): the illustrative default holds nothing, so its builds answer `422`.",
      "item": [
        {
          "id": "8e27f618-0adf-58c7-9e0c-65a1b5ffa0bb",
          "name": "transaction.quote - DEPOSIT",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const isBaseUnits = (value) => typeof value === \"string\" && /^[0-9]+$/.test(value);",
                  "  const isAddress = (value) => typeof value === \"string\" && /^0x[0-9a-fA-F]{40}$/.test(value);",
                  "",
                  "  const data = pm.response.json().data;",
                  "  const sameAddress = (a, b) => typeof a === \"string\" && typeof b === \"string\" && a.toLowerCase() === b.toLowerCase();",
                  "  pm.test(\"the vault and its asset, on mainnet, read at one block\", () => {",
                  "    pm.expect(data.slug).to.eql(pm.variables.get(\"vaultSlug\"));",
                  "    pm.expect(data.chainId).to.eql(1);",
                  "    pm.expect(data.blockNumber).to.be.above(0);",
                  "    pm.expect(isAddress(data.vault.address)).to.eql(true);",
                  "    pm.expect(data.vault.shareDecimals).to.eql(18);",
                  "    pm.expect(isAddress(data.depositAsset.address)).to.eql(true);",
                  "    pm.expect(data.depositAsset.decimals).to.be.a(\"number\");",
                  "    pm.expect(data.notes).to.be.an(\"array\");",
                  "  });",
                  "  pm.test(\"a DEPOSIT of the requested amount\", () => {",
                  "    pm.expect(data.type).to.eql(\"DEPOSIT\");",
                  "    pm.expect(data.amount).to.eql(pm.variables.get(\"depositAmount\"));",
                  "    pm.expect(data.fees.entryBps).to.be.a(\"number\");",
                  "  });",
                  "  pm.test(\"steps: an optional approve, then the deposit\", () => {",
                  "    pm.expect(data.steps[data.steps.length - 1]).to.eql(\"deposit\");",
                  "    pm.expect(data.steps.length === 1 || (data.steps.length === 2 && data.steps[0] === \"approve\")).to.eql(true);",
                  "  });",
                  "  pm.test(\"a quote builds no transaction\", () => {",
                  "    pm.expect(data).to.not.have.property(\"transactions\");",
                  "    pm.expect(data).to.not.have.property(\"simulation\");",
                  "  });",
                  "  pm.test(\"expectedShares is base units, or null when the vault cannot quote now\", () => {",
                  "    pm.expect(data.expectedShares === null || isBaseUnits(data.expectedShares)).to.eql(true);",
                  "  });",
                  "  pm.test(\"availability: depositsOpen, with a reason only when it is false\", () => {",
                  "    pm.expect(data.availability.depositsOpen).to.be.a(\"boolean\");",
                  "    if (data.availability.depositsOpen) pm.expect(data.availability.reason).to.eql(null);",
                  "    else pm.expect(data.availability.reason).to.be.oneOf([\"vault_paused\", \"deposits_unavailable\", \"deposit_cap_reached\"]);",
                  "  });",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/transaction.quote",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "transaction.quote"
              ]
            },
            "description": "`POST {{baseUrl}}/transaction.quote`\n\nPrices a `DEPOSIT` or a `REDEEM_REQUEST` for the vault `slug` names, at one block (`blockNumber`). It builds no transaction.\n\n- `DEPOSIT`: `expectedShares` is `previewSyncDeposit(amount)`, after any entry fee (null when the vault cannot quote now). `availability` says whether the vault takes the deposit now: it is not paused, accepts synchronous deposits with a valid NAV, and has room under its cap, counting the deposits waiting for settlement. It runs no wallet check. With a `sender`, `steps` includes `approve` when its allowance is short.\n- `REDEEM_REQUEST`: `expectedAssets` is the shares' value at the current price, net of the exit fee as the vault settles it; the final amount is fixed at settlement. `window.maxDays` is how long settlement usually takes. With a `sender`, `availability` also checks the vault's allow list, the share balance and a pending redeem request, and `claimFirst` shows a settled redeem request the new one would pay out first.\n- A `DEPOSIT` amount below the minimum or above the per-request limit answers 400 (`amount_below_minimum`, `invalid_amount`).\n- A legacy slug resolves to its canonical vault, and the response carries the canonical slug.\n- Transaction building must be enabled for your API client (403 `actions_not_enabled`) and can be switched off (503 `actions_disabled`).\n\n**Body:** an empty JSON object `{}`. Unknown and duplicate fields are rejected.\n\nSet `vaultSlug` and `depositAmount` (USDC base units, 6 decimals) in the variables. Add `\"sender\": \"{{senderAddress}}\"` to see the approval step.\n\nTransaction building must be enabled for your API client: until Kamui enables it, this request answers `403 actions_not_enabled`.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 DEPOSIT: expected shares, steps and availability",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.quote",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.quote"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "f86a4ac8-f8d0-5106-8df4-17c899c2c965"
                }
              ],
              "body": "{\n  \"data\": {\n    \"type\": \"DEPOSIT\",\n    \"slug\": \"stable-vault\",\n    \"chainId\": 1,\n    \"blockNumber\": 26147329,\n    \"vault\": {\n      \"address\": \"0xcDA323c2DF692d989B24BA51D0aCCa924cf9a344\",\n      \"symbol\": \"USDst\",\n      \"shareDecimals\": 18\n    },\n    \"depositAsset\": {\n      \"address\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n      \"symbol\": \"USDC\",\n      \"decimals\": 6\n    },\n    \"amount\": \"1000000000\",\n    \"expectedShares\": \"997382077837769004220\",\n    \"fees\": {\n      \"entryBps\": 0\n    },\n    \"steps\": [\n      \"deposit\"\n    ],\n    \"notes\": [\n      \"A quote runs no wallet checks and builds no transaction. Call transaction.build with a sender to get the transactions.\"\n    ],\n    \"sender\": null,\n    \"availability\": {\n      \"depositsOpen\": true,\n      \"reason\": null\n    }\n  },\n  \"asOf\": 1791458270\n}"
            },
            {
              "name": "400 Less than 1 USDC",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.quote",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.quote"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"999999\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "b033962d-4357-467f-827a-c7975aaa0a8a"
                }
              ],
              "body": "{\n  \"error\": \"The amount is below the vault minimum.\",\n  \"code\": \"amount_below_minimum\",\n  \"requestId\": \"b033962d-4357-467f-827a-c7975aaa0a8a\",\n  \"details\": [\n    {\n      \"path\": \"body.amount\",\n      \"issue\": \"must be at least 1000000 base units (1 USDC)\"\n    }\n  ]\n}"
            },
            {
              "name": "403 actions_not_enabled",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.quote",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.quote"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Forbidden",
              "code": 403,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "7488d3a9-f4b9-48dc-a258-74a36c9b842b"
                }
              ],
              "body": "{\n  \"error\": \"Transaction building is not enabled for this API client. Contact Kamui.\",\n  \"code\": \"actions_not_enabled\",\n  \"requestId\": \"7488d3a9-f4b9-48dc-a258-74a36c9b842b\"\n}"
            },
            {
              "name": "503 actions_disabled",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.quote",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.quote"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Service Unavailable",
              "code": 503,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "b77ae8f8-85c9-4ddd-a43d-10bbad4c5526"
                }
              ],
              "body": "{\n  \"error\": \"Transaction building is temporarily disabled.\",\n  \"code\": \"actions_disabled\",\n  \"requestId\": \"b77ae8f8-85c9-4ddd-a43d-10bbad4c5526\"\n}"
            },
            {
              "name": "429 rate_limited",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.quote",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.quote"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Too Many Requests",
              "code": 429,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "8e2f4a6c-1b3d-4e5f-9a7b-0c2d4e6f8a1b"
                },
                {
                  "key": "Retry-After",
                  "value": "18"
                },
                {
                  "key": "RateLimit-Policy",
                  "value": "\"actions\";q=20;w=60"
                },
                {
                  "key": "RateLimit",
                  "value": "\"actions\";r=0;t=18"
                },
                {
                  "key": "X-RateLimit-Limit",
                  "value": "20"
                },
                {
                  "key": "X-RateLimit-Remaining",
                  "value": "0"
                },
                {
                  "key": "X-RateLimit-Reset",
                  "value": "1791454980"
                }
              ],
              "body": "{\n  \"error\": \"Too many requests. Wait and try again.\",\n  \"code\": \"rate_limited\",\n  \"requestId\": \"8e2f4a6c-1b3d-4e5f-9a7b-0c2d4e6f8a1b\"\n}"
            }
          ]
        },
        {
          "id": "be9b9aff-371b-5f7b-91ba-3dbf93321ca8",
          "name": "transaction.quote - REDEEM_REQUEST",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const isBaseUnits = (value) => typeof value === \"string\" && /^[0-9]+$/.test(value);",
                  "  const isAddress = (value) => typeof value === \"string\" && /^0x[0-9a-fA-F]{40}$/.test(value);",
                  "",
                  "  const data = pm.response.json().data;",
                  "  const sameAddress = (a, b) => typeof a === \"string\" && typeof b === \"string\" && a.toLowerCase() === b.toLowerCase();",
                  "  pm.test(\"the vault and its asset, on mainnet, read at one block\", () => {",
                  "    pm.expect(data.slug).to.eql(pm.variables.get(\"vaultSlug\"));",
                  "    pm.expect(data.chainId).to.eql(1);",
                  "    pm.expect(data.blockNumber).to.be.above(0);",
                  "    pm.expect(isAddress(data.vault.address)).to.eql(true);",
                  "    pm.expect(data.vault.shareDecimals).to.eql(18);",
                  "    pm.expect(isAddress(data.depositAsset.address)).to.eql(true);",
                  "    pm.expect(data.depositAsset.decimals).to.be.a(\"number\");",
                  "    pm.expect(data.notes).to.be.an(\"array\");",
                  "  });",
                  "  pm.test(\"a REDEEM_REQUEST of the requested shares\", () => {",
                  "    pm.expect(data.type).to.eql(\"REDEEM_REQUEST\");",
                  "    pm.expect(data.shares).to.eql(pm.variables.get(\"redeemShares\"));",
                  "    pm.expect(isBaseUnits(data.expectedAssets)).to.eql(true);",
                  "    pm.expect(data.window.maxDays).to.be.above(0);",
                  "    pm.expect(data.fees.exitBps).to.be.a(\"number\");",
                  "    pm.expect(data.steps).to.eql([\"redeem_request\"]);",
                  "  });",
                  "  pm.test(\"claimFirst is null or the settled assets and shares it pays out first\", () => {",
                  "    if (data.claimFirst !== null) {",
                  "      pm.expect(isBaseUnits(data.claimFirst.assets)).to.eql(true);",
                  "      pm.expect(isBaseUnits(data.claimFirst.shares)).to.eql(true);",
                  "    }",
                  "  });",
                  "  pm.test(\"a quote builds no transaction\", () => {",
                  "    pm.expect(data).to.not.have.property(\"transactions\");",
                  "    pm.expect(data).to.not.have.property(\"simulation\");",
                  "  });",
                  "  pm.test(\"availability: redeemRequestsOpen, with a reason only when it is false\", () => {",
                  "    pm.expect(data.availability.redeemRequestsOpen).to.be.a(\"boolean\");",
                  "    if (data.availability.redeemRequestsOpen) pm.expect(data.availability.reason).to.eql(null);",
                  "    else pm.expect(data.availability.reason).to.be.oneOf([\"vault_paused\", \"wallet_not_allowed\", \"insufficient_shares\", \"redeem_request_already_pending\"]);",
                  "  });",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/transaction.quote",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "transaction.quote"
              ]
            },
            "description": "Quote a redeem request of 250 Stable Vault shares. See the first `transaction.quote` request for the fields and the full description.\n\nSet `redeemShares` (vault share base units, 18 decimals) in the variables. Add `\"sender\": \"{{senderAddress}}\"` to also check the wallet: the allow list, the share balance and a pending redeem request.\n\nTransaction building must be enabled for your API client: until Kamui enables it, this request answers `403 actions_not_enabled`.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"REDEEM_REQUEST\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"shares\": \"{{redeemShares}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 REDEEM_REQUEST: the estimated assets and the settlement window",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.quote",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.quote"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"REDEEM_REQUEST\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"shares\": \"{{redeemShares}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "f99f9b12-7eee-5267-bd98-ec864b0c0aa6"
                }
              ],
              "body": "{\n  \"data\": {\n    \"type\": \"REDEEM_REQUEST\",\n    \"slug\": \"stable-vault\",\n    \"chainId\": 1,\n    \"blockNumber\": 26147329,\n    \"vault\": {\n      \"address\": \"0xcDA323c2DF692d989B24BA51D0aCCa924cf9a344\",\n      \"symbol\": \"USDst\",\n      \"shareDecimals\": 18\n    },\n    \"depositAsset\": {\n      \"address\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n      \"symbol\": \"USDC\",\n      \"decimals\": 6\n    },\n    \"shares\": \"250000000000000000000\",\n    \"expectedAssets\": \"250656198\",\n    \"window\": {\n      \"maxDays\": 1\n    },\n    \"fees\": {\n      \"exitBps\": 0\n    },\n    \"claimFirst\": null,\n    \"steps\": [\n      \"redeem_request\"\n    ],\n    \"notes\": [\n      \"The final amount is fixed at the NAV used when the redeem request settles.\",\n      \"Call transaction.build with a sender to get the transaction.\"\n    ],\n    \"sender\": null,\n    \"availability\": {\n      \"redeemRequestsOpen\": true,\n      \"reason\": null\n    }\n  },\n  \"asOf\": 1791458270\n}"
            }
          ]
        },
        {
          "id": "bce4f7c4-3c16-586c-9d94-906a8e380c8c",
          "name": "transaction.build - DEPOSIT",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const isBaseUnits = (value) => typeof value === \"string\" && /^[0-9]+$/.test(value);",
                  "  const isAddress = (value) => typeof value === \"string\" && /^0x[0-9a-fA-F]{40}$/.test(value);",
                  "",
                  "  const data = pm.response.json().data;",
                  "  const sameAddress = (a, b) => typeof a === \"string\" && typeof b === \"string\" && a.toLowerCase() === b.toLowerCase();",
                  "  pm.test(\"the vault and its asset, on mainnet, read at one block\", () => {",
                  "    pm.expect(data.slug).to.eql(pm.variables.get(\"vaultSlug\"));",
                  "    pm.expect(data.chainId).to.eql(1);",
                  "    pm.expect(data.blockNumber).to.be.above(0);",
                  "    pm.expect(isAddress(data.vault.address)).to.eql(true);",
                  "    pm.expect(data.vault.shareDecimals).to.eql(18);",
                  "    pm.expect(isAddress(data.depositAsset.address)).to.eql(true);",
                  "    pm.expect(data.depositAsset.decimals).to.be.a(\"number\");",
                  "    pm.expect(data.notes).to.be.an(\"array\");",
                  "  });",
                  "  pm.test(\"a DEPOSIT of the requested amount\", () => {",
                  "    pm.expect(data.type).to.eql(\"DEPOSIT\");",
                  "    pm.expect(data.amount).to.eql(pm.variables.get(\"depositAmount\"));",
                  "    pm.expect(data.fees.entryBps).to.be.a(\"number\");",
                  "  });",
                  "  pm.test(\"steps: an optional approve, then the deposit\", () => {",
                  "    pm.expect(data.steps[data.steps.length - 1]).to.eql(\"deposit\");",
                  "    pm.expect(data.steps.length === 1 || (data.steps.length === 2 && data.steps[0] === \"approve\")).to.eql(true);",
                  "  });",
                  "  pm.test(\"built for the sender\", () => pm.expect(sameAddress(data.sender, pm.variables.get(\"senderAddress\"))).to.eql(true));",
                  "  pm.test(\"unsigned transactions in step order, from the sender, on mainnet, with no ETH\", () => {",
                  "    pm.expect(data.transactions.map((tx) => tx.label)).to.eql(data.steps);",
                  "    data.transactions.forEach((tx, index) => {",
                  "      pm.expect(tx.step).to.eql(index + 1);",
                  "      pm.expect(tx.chainId).to.eql(1);",
                  "      pm.expect(tx.from).to.eql(data.sender);",
                  "      pm.expect(tx.data).to.match(/^0x[0-9a-fA-F]{8,}$/);",
                  "      pm.expect(tx.value).to.eql(\"0\");",
                  "      pm.expect(tx.to).to.eql(tx.label === \"approve\" ? data.depositAsset.address : data.vault.address);",
                  "    });",
                  "  });",
                  "  pm.test(\"the shares go to the sender; referral is an address\", () => {",
                  "    pm.expect(data.receiver).to.eql(data.sender);",
                  "    pm.expect(isAddress(data.referral)).to.eql(true);",
                  "    pm.expect(isBaseUnits(data.expectedShares)).to.eql(true);",
                  "  });",
                  "  pm.test(\"simulation: passed or partial, at the response block\", () => {",
                  "    pm.expect(data.simulation.status).to.be.oneOf([\"passed\", \"partial\"]);",
                  "    pm.expect(data.simulation.blockNumber).to.eql(data.blockNumber);",
                  "  });",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/transaction.build",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "transaction.build"
              ]
            },
            "description": "`POST {{baseUrl}}/transaction.build`\n\nBuilds a `DEPOSIT` or a `REDEEM_REQUEST` for the vault `slug` names: it runs the checks below in order (the first failure answers), returns the unsigned transactions and simulates them. Nothing is signed or sent.\n\n`DEPOSIT` (`syncDeposit`: the shares are minted in the same transaction):\n\n- Checks: the amount is at least the minimum and within the per-request limit (400 `amount_below_minimum` / `invalid_amount`); `receiver`, when sent, equals `sender`, compared case-insensitively (400 on `body.receiver`); the vault exists (404 `vault_not_found`) and is active (409 `vault_not_active`); the vault is not paused (409 `vault_paused`); it accepts synchronous deposits and its NAV is valid (409 `deposits_unavailable`); the cap has room, counting the deposits waiting for settlement (409 `deposit_cap_reached`); the vault's allow list (`isAllowed`) accepts the sender and the receiver (403 `wallet_not_allowed`); the sender holds the amount (422 `insufficient_balance`); the simulation passes (422 `simulation_failed`).\n- The transactions are an exact-amount `approve` of the deposit asset when the allowance is short, then `syncDeposit(amount, sender, referral)` on the vault: the shares go to the sender. `referral` defaults to the zero address.\n\n`REDEEM_REQUEST`, a redeem request (`requestRedeem(shares, sender, sender)`: the shares leave the wallet at once, and the assets become claimable when the vault settles the request, usually within `window.maxDays`):\n\n- Checks: the vault exists and is active (404 / 409); the vault is not paused (409 `vault_paused`); the vault's allow list accepts the sender (403 `wallet_not_allowed`); `shares` is at most the sender's balance (422 `insufficient_shares`); the sender has no redeem request waiting for settlement in this vault (409 `redeem_request_already_pending`); the simulation passes (422 `simulation_failed`).\n- If the sender has a settled redeem request it has not claimed, `requestRedeem` pays those assets to the sender first, in the same transaction; `claimFirst` shows them (null otherwise). Once the new redeem request settles, the wallet claims its assets in the Kamui app, or its next redeem request pays them out.\n- No approval is needed: the sender owns the shares.\n\nBoth types:\n\n- `simulation.status` is `passed` (the bundle ran with `eth_simulateV1`, or a single transaction with `eth_call`), `partial` (the node cannot simulate a bundle and the deposit needs the approval first, so only the checks ran) or `skipped` (`skipSimulation: true`).\n- A legacy slug resolves to its canonical vault, and the response carries the canonical slug.\n- Transaction building must be enabled for your API client (403 `actions_not_enabled`) and can be switched off (503 `actions_disabled`). A `DEPOSIT`'s amount and receiver checks answer first.\n\n**Body:** an empty JSON object `{}`. Unknown and duplicate fields are rejected.\n\nSet `senderAddress` to the wallet that will sign and send, and `depositAmount` in the variables. The answer's `transactions` are unsigned: sign and send them in `step` order with your wallet stack.\n\nTransaction building must be enabled for your API client: until Kamui enables it, this request answers `403 actions_not_enabled`.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\",\n  \"sender\": \"{{senderAddress}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 DEPOSIT: an exact approval, then the deposit, simulated together",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.build",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.build"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\",\n  \"sender\": \"{{senderAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "7b7f8cc5-4b1d-51c8-b480-9a8fe46202d4"
                }
              ],
              "body": "{\n  \"data\": {\n    \"type\": \"DEPOSIT\",\n    \"slug\": \"stable-vault\",\n    \"chainId\": 1,\n    \"blockNumber\": 26147329,\n    \"vault\": {\n      \"address\": \"0xcDA323c2DF692d989B24BA51D0aCCa924cf9a344\",\n      \"symbol\": \"USDst\",\n      \"shareDecimals\": 18\n    },\n    \"depositAsset\": {\n      \"address\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n      \"symbol\": \"USDC\",\n      \"decimals\": 6\n    },\n    \"amount\": \"1000000000\",\n    \"expectedShares\": \"997382077837769004220\",\n    \"fees\": {\n      \"entryBps\": 0\n    },\n    \"steps\": [\n      \"approve\",\n      \"deposit\"\n    ],\n    \"notes\": [\n      \"Send the transactions in step order and wait for each receipt before you send the next.\",\n      \"Shares are minted at the vault price when the deposit executes; expectedShares uses the price at blockNumber.\",\n      \"Build again after a 409, or when more than 10 minutes have passed.\"\n    ],\n    \"sender\": \"0x1111111111111111111111111111111111111111\",\n    \"receiver\": \"0x1111111111111111111111111111111111111111\",\n    \"referral\": \"0x0000000000000000000000000000000000000000\",\n    \"transactions\": [\n      {\n        \"step\": 1,\n        \"label\": \"approve\",\n        \"description\": \"Approve the vault to transfer exactly the deposit amount of the deposit asset.\",\n        \"chainId\": 1,\n        \"from\": \"0x1111111111111111111111111111111111111111\",\n        \"to\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n        \"data\": \"0x095ea7b3000000000000000000000000cda323c2df692d989b24ba51d0acca924cf9a344000000000000000000000000000000000000000000000000000000003b9aca00\",\n        \"value\": \"0\"\n      },\n      {\n        \"step\": 2,\n        \"label\": \"deposit\",\n        \"description\": \"Deposit assets into the vault and receive vault shares in the same transaction.\",\n        \"chainId\": 1,\n        \"from\": \"0x1111111111111111111111111111111111111111\",\n        \"to\": \"0xcDA323c2DF692d989B24BA51D0aCCa924cf9a344\",\n        \"data\": \"0xd01d073a000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000011111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000000000\",\n        \"value\": \"0\"\n      }\n    ],\n    \"simulation\": {\n      \"status\": \"passed\",\n      \"method\": \"eth_simulateV1\",\n      \"blockNumber\": 26147329\n    }\n  },\n  \"asOf\": 1791458270\n}"
            },
            {
              "name": "403 wallet_not_allowed",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.build",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.build"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\",\n  \"sender\": \"{{senderAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Forbidden",
              "code": 403,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "f380ff7f-af51-432a-9691-36bbc1b6903d"
                }
              ],
              "body": "{\n  \"error\": \"This wallet is not allowed to use this vault.\",\n  \"code\": \"wallet_not_allowed\",\n  \"requestId\": \"f380ff7f-af51-432a-9691-36bbc1b6903d\"\n}"
            },
            {
              "name": "409 vault_paused",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.build",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.build"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\",\n  \"sender\": \"{{senderAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Conflict",
              "code": 409,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "f196a4b2-8340-4fd3-ae58-f7b5dbda7106"
                }
              ],
              "body": "{\n  \"error\": \"Deposits and redeem requests are paused for this vault.\",\n  \"code\": \"vault_paused\",\n  \"requestId\": \"f196a4b2-8340-4fd3-ae58-f7b5dbda7106\"\n}"
            },
            {
              "name": "409 deposits_unavailable: The vault does not accept synchronous deposits now.",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.build",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.build"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\",\n  \"sender\": \"{{senderAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Conflict",
              "code": 409,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "5281edf8-46e8-4c60-8c7f-3db3f5cb5c20"
                }
              ],
              "body": "{\n  \"error\": \"Deposits are temporarily unavailable for this vault. Try again later.\",\n  \"code\": \"deposits_unavailable\",\n  \"requestId\": \"5281edf8-46e8-4c60-8c7f-3db3f5cb5c20\"\n}"
            },
            {
              "name": "409 deposit_cap_reached: The deposit would exceed the vault's cap.",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.build",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.build"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\",\n  \"sender\": \"{{senderAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Conflict",
              "code": 409,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "849ab219-22d6-46df-b658-c34d63bd6082"
                }
              ],
              "body": "{\n  \"error\": \"This deposit would exceed the vault capacity.\",\n  \"code\": \"deposit_cap_reached\",\n  \"requestId\": \"849ab219-22d6-46df-b658-c34d63bd6082\"\n}"
            },
            {
              "name": "422 insufficient_balance",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.build",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.build"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\",\n  \"sender\": \"{{senderAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "812765a5-46fa-4fee-8f07-82cfeabc46cf"
                }
              ],
              "body": "{\n  \"error\": \"The wallet balance is lower than the amount.\",\n  \"code\": \"insufficient_balance\",\n  \"requestId\": \"812765a5-46fa-4fee-8f07-82cfeabc46cf\"\n}"
            },
            {
              "name": "422 simulation_failed: A built transaction reverts in simulation.",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.build",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.build"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\",\n  \"sender\": \"{{senderAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "4daebf0a-dae7-4ec2-a17d-2c2d6d8cff74"
                }
              ],
              "body": "{\n  \"error\": \"The transaction would fail onchain. See details.\",\n  \"code\": \"simulation_failed\",\n  \"requestId\": \"4daebf0a-dae7-4ec2-a17d-2c2d6d8cff74\",\n  \"details\": [\n    {\n      \"path\": \"transactions.1\",\n      \"issue\": \"step 2 (deposit) reverts: EnforcedPause (selector 0xd93c0665)\"\n    }\n  ]\n}"
            },
            {
              "name": "403 actions_not_enabled",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.build",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.build"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\",\n  \"sender\": \"{{senderAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Forbidden",
              "code": 403,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "7488d3a9-f4b9-48dc-a258-74a36c9b842b"
                }
              ],
              "body": "{\n  \"error\": \"Transaction building is not enabled for this API client. Contact Kamui.\",\n  \"code\": \"actions_not_enabled\",\n  \"requestId\": \"7488d3a9-f4b9-48dc-a258-74a36c9b842b\"\n}"
            },
            {
              "name": "503 actions_disabled",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.build",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.build"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\",\n  \"sender\": \"{{senderAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Service Unavailable",
              "code": 503,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "b77ae8f8-85c9-4ddd-a43d-10bbad4c5526"
                }
              ],
              "body": "{\n  \"error\": \"Transaction building is temporarily disabled.\",\n  \"code\": \"actions_disabled\",\n  \"requestId\": \"b77ae8f8-85c9-4ddd-a43d-10bbad4c5526\"\n}"
            },
            {
              "name": "429 rate_limited",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.build",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.build"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\",\n  \"sender\": \"{{senderAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Too Many Requests",
              "code": 429,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "8e2f4a6c-1b3d-4e5f-9a7b-0c2d4e6f8a1b"
                },
                {
                  "key": "Retry-After",
                  "value": "18"
                },
                {
                  "key": "RateLimit-Policy",
                  "value": "\"actions\";q=20;w=60"
                },
                {
                  "key": "RateLimit",
                  "value": "\"actions\";r=0;t=18"
                },
                {
                  "key": "X-RateLimit-Limit",
                  "value": "20"
                },
                {
                  "key": "X-RateLimit-Remaining",
                  "value": "0"
                },
                {
                  "key": "X-RateLimit-Reset",
                  "value": "1791454980"
                }
              ],
              "body": "{\n  \"error\": \"Too many requests. Wait and try again.\",\n  \"code\": \"rate_limited\",\n  \"requestId\": \"8e2f4a6c-1b3d-4e5f-9a7b-0c2d4e6f8a1b\"\n}"
            }
          ]
        },
        {
          "id": "7405ae4b-f813-5cbf-8274-f4112bfcf77a",
          "name": "transaction.build - DEPOSIT without simulation",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const isBaseUnits = (value) => typeof value === \"string\" && /^[0-9]+$/.test(value);",
                  "  const isAddress = (value) => typeof value === \"string\" && /^0x[0-9a-fA-F]{40}$/.test(value);",
                  "",
                  "  const data = pm.response.json().data;",
                  "  const sameAddress = (a, b) => typeof a === \"string\" && typeof b === \"string\" && a.toLowerCase() === b.toLowerCase();",
                  "  pm.test(\"the vault and its asset, on mainnet, read at one block\", () => {",
                  "    pm.expect(data.slug).to.eql(pm.variables.get(\"vaultSlug\"));",
                  "    pm.expect(data.chainId).to.eql(1);",
                  "    pm.expect(data.blockNumber).to.be.above(0);",
                  "    pm.expect(isAddress(data.vault.address)).to.eql(true);",
                  "    pm.expect(data.vault.shareDecimals).to.eql(18);",
                  "    pm.expect(isAddress(data.depositAsset.address)).to.eql(true);",
                  "    pm.expect(data.depositAsset.decimals).to.be.a(\"number\");",
                  "    pm.expect(data.notes).to.be.an(\"array\");",
                  "  });",
                  "  pm.test(\"a DEPOSIT of the requested amount\", () => {",
                  "    pm.expect(data.type).to.eql(\"DEPOSIT\");",
                  "    pm.expect(data.amount).to.eql(pm.variables.get(\"depositAmount\"));",
                  "    pm.expect(data.fees.entryBps).to.be.a(\"number\");",
                  "  });",
                  "  pm.test(\"steps: an optional approve, then the deposit\", () => {",
                  "    pm.expect(data.steps[data.steps.length - 1]).to.eql(\"deposit\");",
                  "    pm.expect(data.steps.length === 1 || (data.steps.length === 2 && data.steps[0] === \"approve\")).to.eql(true);",
                  "  });",
                  "  pm.test(\"built for the sender\", () => pm.expect(sameAddress(data.sender, pm.variables.get(\"senderAddress\"))).to.eql(true));",
                  "  pm.test(\"unsigned transactions in step order, from the sender, on mainnet, with no ETH\", () => {",
                  "    pm.expect(data.transactions.map((tx) => tx.label)).to.eql(data.steps);",
                  "    data.transactions.forEach((tx, index) => {",
                  "      pm.expect(tx.step).to.eql(index + 1);",
                  "      pm.expect(tx.chainId).to.eql(1);",
                  "      pm.expect(tx.from).to.eql(data.sender);",
                  "      pm.expect(tx.data).to.match(/^0x[0-9a-fA-F]{8,}$/);",
                  "      pm.expect(tx.value).to.eql(\"0\");",
                  "      pm.expect(tx.to).to.eql(tx.label === \"approve\" ? data.depositAsset.address : data.vault.address);",
                  "    });",
                  "  });",
                  "  pm.test(\"the shares go to the sender; referral is an address\", () => {",
                  "    pm.expect(data.receiver).to.eql(data.sender);",
                  "    pm.expect(isAddress(data.referral)).to.eql(true);",
                  "    pm.expect(isBaseUnits(data.expectedShares)).to.eql(true);",
                  "  });",
                  "  pm.test(\"simulation: skipped, at the response block\", () => {",
                  "    pm.expect(data.simulation.status).to.be.oneOf([\"skipped\"]);",
                  "    pm.expect(data.simulation.blockNumber).to.eql(data.blockNumber);",
                  "  });",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/transaction.build",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "transaction.build"
              ]
            },
            "description": "The DEPOSIT build with `skipSimulation: true`: every check still runs, and `simulation.status` is `skipped`. See **transaction.build - DEPOSIT** for the fields and the full description.\n\nTransaction building must be enabled for your API client: until Kamui enables it, this request answers `403 actions_not_enabled`.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\",\n  \"sender\": \"{{senderAddress}}\",\n  \"skipSimulation\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "id": "bc859eee-d332-5d70-a17e-ce07f7394a78",
          "name": "transaction.build - REDEEM_REQUEST",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"200 OK\", () => pm.response.to.have.status(200));",
                  "if (pm.response.code === 200) {",
                  "  const isBaseUnits = (value) => typeof value === \"string\" && /^[0-9]+$/.test(value);",
                  "  const isAddress = (value) => typeof value === \"string\" && /^0x[0-9a-fA-F]{40}$/.test(value);",
                  "",
                  "  const data = pm.response.json().data;",
                  "  const sameAddress = (a, b) => typeof a === \"string\" && typeof b === \"string\" && a.toLowerCase() === b.toLowerCase();",
                  "  pm.test(\"the vault and its asset, on mainnet, read at one block\", () => {",
                  "    pm.expect(data.slug).to.eql(pm.variables.get(\"vaultSlug\"));",
                  "    pm.expect(data.chainId).to.eql(1);",
                  "    pm.expect(data.blockNumber).to.be.above(0);",
                  "    pm.expect(isAddress(data.vault.address)).to.eql(true);",
                  "    pm.expect(data.vault.shareDecimals).to.eql(18);",
                  "    pm.expect(isAddress(data.depositAsset.address)).to.eql(true);",
                  "    pm.expect(data.depositAsset.decimals).to.be.a(\"number\");",
                  "    pm.expect(data.notes).to.be.an(\"array\");",
                  "  });",
                  "  pm.test(\"a REDEEM_REQUEST of the requested shares\", () => {",
                  "    pm.expect(data.type).to.eql(\"REDEEM_REQUEST\");",
                  "    pm.expect(data.shares).to.eql(pm.variables.get(\"redeemShares\"));",
                  "    pm.expect(isBaseUnits(data.expectedAssets)).to.eql(true);",
                  "    pm.expect(data.window.maxDays).to.be.above(0);",
                  "    pm.expect(data.fees.exitBps).to.be.a(\"number\");",
                  "    pm.expect(data.steps).to.eql([\"redeem_request\"]);",
                  "  });",
                  "  pm.test(\"claimFirst is null or the settled assets and shares it pays out first\", () => {",
                  "    if (data.claimFirst !== null) {",
                  "      pm.expect(isBaseUnits(data.claimFirst.assets)).to.eql(true);",
                  "      pm.expect(isBaseUnits(data.claimFirst.shares)).to.eql(true);",
                  "    }",
                  "  });",
                  "  pm.test(\"built for the sender\", () => pm.expect(sameAddress(data.sender, pm.variables.get(\"senderAddress\"))).to.eql(true));",
                  "  pm.test(\"unsigned transactions in step order, from the sender, on mainnet, with no ETH\", () => {",
                  "    pm.expect(data.transactions.map((tx) => tx.label)).to.eql(data.steps);",
                  "    data.transactions.forEach((tx, index) => {",
                  "      pm.expect(tx.step).to.eql(index + 1);",
                  "      pm.expect(tx.chainId).to.eql(1);",
                  "      pm.expect(tx.from).to.eql(data.sender);",
                  "      pm.expect(tx.data).to.match(/^0x[0-9a-fA-F]{8,}$/);",
                  "      pm.expect(tx.value).to.eql(\"0\");",
                  "      pm.expect(tx.to).to.eql(tx.label === \"approve\" ? data.depositAsset.address : data.vault.address);",
                  "    });",
                  "  });",
                  "  pm.test(\"simulation: passed, at the response block\", () => {",
                  "    pm.expect(data.simulation.status).to.be.oneOf([\"passed\"]);",
                  "    pm.expect(data.simulation.blockNumber).to.eql(data.blockNumber);",
                  "  });",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/transaction.build",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "transaction.build"
              ]
            },
            "description": "Build a redeem request of 250 shares for a wallet (illustrative address). See the first `transaction.build` request for the fields and the full description.\n\nSet `senderAddress` and `redeemShares` in the variables. Once the redeem request settles, the wallet claims its assets in the Kamui app, or its next redeem request pays them out (`claimFirst`).\n\nTransaction building must be enabled for your API client: until Kamui enables it, this request answers `403 actions_not_enabled`.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"REDEEM_REQUEST\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"shares\": \"{{redeemShares}}\",\n  \"sender\": \"{{senderAddress}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "200 REDEEM_REQUEST: one requestRedeem transaction",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.build",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.build"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"REDEEM_REQUEST\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"shares\": \"{{redeemShares}}\",\n  \"sender\": \"{{senderAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "c93ec23c-f58a-504f-940b-0f6d2b775b51"
                }
              ],
              "body": "{\n  \"data\": {\n    \"type\": \"REDEEM_REQUEST\",\n    \"slug\": \"stable-vault\",\n    \"chainId\": 1,\n    \"blockNumber\": 26147329,\n    \"vault\": {\n      \"address\": \"0xcDA323c2DF692d989B24BA51D0aCCa924cf9a344\",\n      \"symbol\": \"USDst\",\n      \"shareDecimals\": 18\n    },\n    \"depositAsset\": {\n      \"address\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n      \"symbol\": \"USDC\",\n      \"decimals\": 6\n    },\n    \"shares\": \"250000000000000000000\",\n    \"expectedAssets\": \"250656198\",\n    \"window\": {\n      \"maxDays\": 1\n    },\n    \"fees\": {\n      \"exitBps\": 0\n    },\n    \"claimFirst\": null,\n    \"steps\": [\n      \"redeem_request\"\n    ],\n    \"notes\": [\n      \"The final amount is fixed at the NAV used when the redeem request settles.\",\n      \"After settlement the assets are claimable: the wallet claims them in the Kamui app, or Lagoon pays them in the wallet's next redeem request.\",\n      \"Build again after a 409, or when more than 10 minutes have passed.\"\n    ],\n    \"sender\": \"0x1111111111111111111111111111111111111111\",\n    \"transactions\": [\n      {\n        \"step\": 1,\n        \"label\": \"redeem_request\",\n        \"description\": \"Create a redeem request for vault shares. The assets become claimable after the vault settles the request.\",\n        \"chainId\": 1,\n        \"from\": \"0x1111111111111111111111111111111111111111\",\n        \"to\": \"0xcDA323c2DF692d989B24BA51D0aCCa924cf9a344\",\n        \"data\": \"0x7d41c86e00000000000000000000000000000000000000000000000d8d726b7177a8000000000000000000000000000011111111111111111111111111111111111111110000000000000000000000001111111111111111111111111111111111111111\",\n        \"value\": \"0\"\n      }\n    ],\n    \"simulation\": {\n      \"status\": \"passed\",\n      \"method\": \"eth_simulateV1\",\n      \"blockNumber\": 26147329\n    }\n  },\n  \"asOf\": 1791458270\n}"
            },
            {
              "name": "200 REDEEM_REQUEST while an earlier redeem request is claimable: requestRedeem pays...",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.build",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.build"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"REDEEM_REQUEST\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"shares\": \"{{redeemShares}}\",\n  \"sender\": \"{{senderAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "92718993-e9fe-5a23-b43c-83bc1e4b385b"
                }
              ],
              "body": "{\n  \"data\": {\n    \"type\": \"REDEEM_REQUEST\",\n    \"slug\": \"stable-vault\",\n    \"chainId\": 1,\n    \"blockNumber\": 26147329,\n    \"vault\": {\n      \"address\": \"0xcDA323c2DF692d989B24BA51D0aCCa924cf9a344\",\n      \"symbol\": \"USDst\",\n      \"shareDecimals\": 18\n    },\n    \"depositAsset\": {\n      \"address\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n      \"symbol\": \"USDC\",\n      \"decimals\": 6\n    },\n    \"shares\": \"250000000000000000000\",\n    \"expectedAssets\": \"250656198\",\n    \"window\": {\n      \"maxDays\": 1\n    },\n    \"fees\": {\n      \"exitBps\": 0\n    },\n    \"claimFirst\": {\n      \"assets\": \"250545500\",\n      \"shares\": \"250000000000000000000\"\n    },\n    \"steps\": [\n      \"redeem_request\"\n    ],\n    \"notes\": [\n      \"The final amount is fixed at the NAV used when the redeem request settles.\",\n      \"After settlement the assets are claimable: the wallet claims them in the Kamui app, or Lagoon pays them in the wallet's next redeem request.\",\n      \"Build again after a 409, or when more than 10 minutes have passed.\",\n      \"The sender has a settled redeem request to claim (claimFirst): the requestRedeem transaction pays those assets to the sender before it opens the new request.\"\n    ],\n    \"sender\": \"0x1111111111111111111111111111111111111111\",\n    \"transactions\": [\n      {\n        \"step\": 1,\n        \"label\": \"redeem_request\",\n        \"description\": \"Create a redeem request for vault shares. The assets become claimable after the vault settles the request.\",\n        \"chainId\": 1,\n        \"from\": \"0x1111111111111111111111111111111111111111\",\n        \"to\": \"0xcDA323c2DF692d989B24BA51D0aCCa924cf9a344\",\n        \"data\": \"0x7d41c86e00000000000000000000000000000000000000000000000d8d726b7177a8000000000000000000000000000011111111111111111111111111111111111111110000000000000000000000001111111111111111111111111111111111111111\",\n        \"value\": \"0\"\n      }\n    ],\n    \"simulation\": {\n      \"status\": \"passed\",\n      \"method\": \"eth_simulateV1\",\n      \"blockNumber\": 26147329\n    }\n  },\n  \"asOf\": 1791458270\n}"
            },
            {
              "name": "409 redeem_request_already_pending: The sender already has a redeem request waiting for settlement in this vault.",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.build",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.build"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"REDEEM_REQUEST\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"shares\": \"{{redeemShares}}\",\n  \"sender\": \"{{senderAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Conflict",
              "code": 409,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "08512f3a-a739-40df-822c-82e773f176aa"
                }
              ],
              "body": "{\n  \"error\": \"This wallet already has a pending redeem request for this vault.\",\n  \"code\": \"redeem_request_already_pending\",\n  \"requestId\": \"08512f3a-a739-40df-822c-82e773f176aa\"\n}"
            },
            {
              "name": "422 insufficient_shares: The sender holds fewer shares than the redeem request.",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.build",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.build"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"REDEEM_REQUEST\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"shares\": \"{{redeemShares}}\",\n  \"sender\": \"{{senderAddress}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Unprocessable Entity",
              "code": 422,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "16f03ad6-c2c5-4cfb-a408-e1eb8e063a24"
                }
              ],
              "body": "{\n  \"error\": \"The wallet holds fewer shares than requested.\",\n  \"code\": \"insufficient_shares\",\n  \"requestId\": \"16f03ad6-c2c5-4cfb-a408-e1eb8e063a24\"\n}"
            }
          ]
        }
      ]
    },
    {
      "id": "6d7a6d07-3e38-507f-b2f5-bed94cf4896f",
      "name": "Errors",
      "description": "Requests that fail on purpose, one per error you can trigger without a funded wallet. Each test checks the status and the `code`. Branch on `code` in your integration; the `error` text may change.\n\n`409 vault_not_active`, `500 internal_error`, `502 upstream_error`, `503 service_unavailable` / `history_unavailable` and `504 upstream_timeout` cannot be triggered on demand. Retry `5xx` answers with backoff. Saved examples of `409` and `503 history_unavailable` are on **vaults.history - share price** and **users.transactions - first page**. The transaction errors that depend on the wallet or the vault (`403`, `409`, `422`) have saved examples on the **Transactions** requests.",
      "item": [
        {
          "id": "f31ced8d-7b5e-519b-bf1f-e43dcf16cd00",
          "name": "401 - missing API key",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"401 Unauthorized\", () => pm.response.to.have.status(401));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is unauthorized\", () => pm.expect(body.code).to.eql(\"unauthorized\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/health.ping",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "health.ping"
              ]
            },
            "description": "Sent without `x-partner-api-key`. A missing, malformed, unknown, revoked or expired key all get this same 401.",
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [
            {
              "name": "401 The API key is missing, malformed, unknown, revoked or expired.",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/health.ping",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "health.ping"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "auth": {
                  "type": "noauth"
                }
              },
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "ea80702c-a332-4e32-922e-76bcb02e6156"
                }
              ],
              "body": "{\n  \"error\": \"Unauthorized.\",\n  \"code\": \"unauthorized\",\n  \"requestId\": \"ea80702c-a332-4e32-922e-76bcb02e6156\"\n}"
            }
          ]
        },
        {
          "id": "d513cba4-5f14-5af9-b05e-59f665c25d0c",
          "name": "401 - unknown API key",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"401 Unauthorized\", () => pm.response.to.have.status(401));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is unauthorized\", () => pm.expect(body.code).to.eql(\"unauthorized\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/health.ping",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "health.ping"
              ]
            },
            "description": "Sent with a well-formed key that Kamui never issued. Same 401 as a missing key.",
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "auth": {
              "type": "apikey",
              "apikey": [
                {
                  "key": "key",
                  "value": "x-partner-api-key",
                  "type": "string"
                },
                {
                  "key": "value",
                  "value": "kmi_notarealkey2_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
                  "type": "string"
                },
                {
                  "key": "in",
                  "value": "header",
                  "type": "string"
                }
              ]
            }
          },
          "response": [
            {
              "name": "401 The API key is missing, malformed, unknown, revoked or expired.",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/health.ping",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "health.ping"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "auth": {
                  "type": "apikey",
                  "apikey": [
                    {
                      "key": "key",
                      "value": "x-partner-api-key",
                      "type": "string"
                    },
                    {
                      "key": "value",
                      "value": "kmi_notarealkey2_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
                      "type": "string"
                    },
                    {
                      "key": "in",
                      "value": "header",
                      "type": "string"
                    }
                  ]
                }
              },
              "status": "Unauthorized",
              "code": 401,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "ea80702c-a332-4e32-922e-76bcb02e6156"
                }
              ],
              "body": "{\n  \"error\": \"Unauthorized.\",\n  \"code\": \"unauthorized\",\n  \"requestId\": \"ea80702c-a332-4e32-922e-76bcb02e6156\"\n}"
            }
          ]
        },
        {
          "id": "4b735835-c12c-5bb2-bf31-0500c5790dcc",
          "name": "400 - unknown field",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is invalid_request\", () => pm.expect(body.code).to.eql(\"invalid_request\"));",
                  "pm.test(\"details name body.foo\", () => pm.expect((body.details || []).map((d) => d.path)).to.include(\"body.foo\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/health.ping",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "health.ping"
              ]
            },
            "description": "`health.ping`: bodies are strict, so a field the action does not define is rejected. `details` names it.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"foo\": 1\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 Unknown field in the body",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/health.ping",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "health.ping"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"foo\": 1\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "a5ba5c77-7339-4e12-b2cf-3c1f848f8da8"
                }
              ],
              "body": "{\n  \"error\": \"The request is not valid. See details.\",\n  \"code\": \"invalid_request\",\n  \"requestId\": \"a5ba5c77-7339-4e12-b2cf-3c1f848f8da8\",\n  \"details\": [\n    {\n      \"path\": \"body.foo\",\n      \"issue\": \"is not a known field\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "a3d6ff22-8f8b-5c05-a169-cb1ce2fb36b0",
          "name": "400 - invalid address",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is invalid_request\", () => pm.expect(body.code).to.eql(\"invalid_request\"));",
                  "pm.test(\"details name body.address\", () => pm.expect((body.details || []).map((d) => d.path)).to.include(\"body.address\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/users.positions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "users.positions"
              ]
            },
            "description": "`users.positions`: an address must be `0x` plus 40 hex characters (lowercase or EIP-55).",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"address\": \"0x1234\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 Address of the wrong length",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/users.positions",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "users.positions"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"address\": \"0x1234\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "427a956d-6fe0-47da-ad42-e666aa432840"
                }
              ],
              "body": "{\n  \"error\": \"The request is not valid. See details.\",\n  \"code\": \"invalid_request\",\n  \"requestId\": \"427a956d-6fe0-47da-ad42-e666aa432840\",\n  \"details\": [\n    {\n      \"path\": \"body.address\",\n      \"issue\": \"must be 42 characters long\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "2f7e8f15-2b02-59e3-8928-488c940e5e8e",
          "name": "400 - zero address",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is invalid_request\", () => pm.expect(body.code).to.eql(\"invalid_request\"));",
                  "pm.test(\"details name body.address\", () => pm.expect((body.details || []).map((d) => d.path)).to.include(\"body.address\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/users.positions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "users.positions"
              ]
            },
            "description": "`users.positions`: the zero address is rejected.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"address\": \"0x0000000000000000000000000000000000000000\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 The zero address",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/users.positions",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "users.positions"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"address\": \"0x0000000000000000000000000000000000000000\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "c2b0f7a1-5d3e-4c8b-9a61-0f2e7d4b8c13"
                }
              ],
              "body": "{\n  \"error\": \"The request is not valid. See details.\",\n  \"code\": \"invalid_request\",\n  \"requestId\": \"c2b0f7a1-5d3e-4c8b-9a61-0f2e7d4b8c13\",\n  \"details\": [\n    {\n      \"path\": \"body.address\",\n      \"issue\": \"must not be the zero address\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "dc83247f-eede-5bf4-8e29-5454bcc563f1",
          "name": "400 - missing slug",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is invalid_request\", () => pm.expect(body.code).to.eql(\"invalid_request\"));",
                  "pm.test(\"details name body.slug\", () => pm.expect((body.details || []).map((d) => d.path)).to.include(\"body.slug\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/vaults.get",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "vaults.get"
              ]
            },
            "description": "`vaults.get`: `slug` is required.",
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 No slug",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/vaults.get",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "vaults.get"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "28cb92f3-7956-4e57-b1e0-2af164368a83"
                }
              ],
              "body": "{\n  \"error\": \"The request is not valid. See details.\",\n  \"code\": \"invalid_request\",\n  \"requestId\": \"28cb92f3-7956-4e57-b1e0-2af164368a83\",\n  \"details\": [\n    {\n      \"path\": \"body.slug\",\n      \"issue\": \"Invalid input: expected string, received undefined\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "56ae36f9-da93-5bf9-9a09-6c47b5c96ef9",
          "name": "400 - invalid slug",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is invalid_request\", () => pm.expect(body.code).to.eql(\"invalid_request\"));",
                  "pm.test(\"details name body.slug\", () => pm.expect((body.details || []).map((d) => d.path)).to.include(\"body.slug\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/vaults.get",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "vaults.get"
              ]
            },
            "description": "`vaults.get`: a slug is lowercase letters, digits and single hyphens. A well-formed slug that matches no vault is a 404 instead.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"slug\": \"Stable Vault\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 A slug with spaces or capitals",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/vaults.get",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "vaults.get"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"slug\": \"Stable Vault\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "3733ee07-fe43-4965-a33b-ae7ab8d77173"
                }
              ],
              "body": "{\n  \"error\": \"The request is not valid. See details.\",\n  \"code\": \"invalid_request\",\n  \"requestId\": \"3733ee07-fe43-4965-a33b-ae7ab8d77173\",\n  \"details\": [\n    {\n      \"path\": \"body.slug\",\n      \"issue\": \"must be lowercase letters, digits and single hyphens\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "4e0006f7-5049-5ae4-851a-ad3e8b215d8a",
          "name": "400 - duplicate field",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is invalid_request\", () => pm.expect(body.code).to.eql(\"invalid_request\"));",
                  "pm.test(\"details name body.slug\", () => pm.expect((body.details || []).map((d) => d.path)).to.include(\"body.slug\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/vaults.get",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "vaults.get"
              ]
            },
            "description": "`vaults.get`: a field may appear only once in an object, even with the same value. `details` names it with the issue `is a duplicate field`.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"slug\": \"{{vaultSlug}}\",\n  \"slug\": \"{{vaultSlug}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 A field sent twice",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/vaults.get",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "vaults.get"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"slug\": \"{{vaultSlug}}\",\n  \"slug\": \"{{vaultSlug}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "6b0f4c2e-9d1a-4e57-8c3b-2a7d5e9f1c04"
                }
              ],
              "body": "{\n  \"error\": \"The request is not valid. See details.\",\n  \"code\": \"invalid_request\",\n  \"requestId\": \"6b0f4c2e-9d1a-4e57-8c3b-2a7d5e9f1c04\",\n  \"details\": [\n    {\n      \"path\": \"body.slug\",\n      \"issue\": \"is a duplicate field\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "0a854ace-8cb2-5672-acd8-be0b0cfb8807",
          "name": "400 - unknown metric",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is invalid_request\", () => pm.expect(body.code).to.eql(\"invalid_request\"));",
                  "pm.test(\"details name body.metric\", () => pm.expect((body.details || []).map((d) => d.path)).to.include(\"body.metric\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/vaults.history",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "vaults.history"
              ]
            },
            "description": "`vaults.history`: `metric` is `share_price` or `tvl`.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"slug\": \"{{vaultSlug}}\",\n  \"metric\": \"price\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 Unknown metric",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/vaults.history",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "vaults.history"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"slug\": \"{{vaultSlug}}\",\n  \"metric\": \"price\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "bd6dfdcb-2d50-46b2-af72-786c15b1cf82"
                }
              ],
              "body": "{\n  \"error\": \"The request is not valid. See details.\",\n  \"code\": \"invalid_request\",\n  \"requestId\": \"bd6dfdcb-2d50-46b2-af72-786c15b1cf82\",\n  \"details\": [\n    {\n      \"path\": \"body.metric\",\n      \"issue\": \"Invalid option: expected one of \\\"share_price\\\"|\\\"tvl\\\"\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "a10d13da-a61c-5eb7-857e-6adf0a2d4978",
          "name": "400 - from is not before to",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is invalid_request\", () => pm.expect(body.code).to.eql(\"invalid_request\"));",
                  "pm.test(\"details name body.from\", () => pm.expect((body.details || []).map((d) => d.path)).to.include(\"body.from\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/vaults.history",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "vaults.history"
              ]
            },
            "description": "`vaults.history`: `from` must be before `to`, and the range may be at most 366 days.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"slug\": \"{{vaultSlug}}\",\n  \"metric\": \"share_price\",\n  \"from\": 1791417600,\n  \"to\": 1788825600\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 from is not before to",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/vaults.history",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "vaults.history"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"slug\": \"{{vaultSlug}}\",\n  \"metric\": \"share_price\",\n  \"from\": 1791417600,\n  \"to\": 1788825600\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "a595eee8-ac82-4aa9-9ec5-d31750f583c3"
                }
              ],
              "body": "{\n  \"error\": \"The request is not valid. See details.\",\n  \"code\": \"invalid_request\",\n  \"requestId\": \"a595eee8-ac82-4aa9-9ec5-d31750f583c3\",\n  \"details\": [\n    {\n      \"path\": \"body.from\",\n      \"issue\": \"must be before to\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "50164805-799b-5cf6-b162-5841bdd2941a",
          "name": "400 - users.transactions with an unknown type",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is invalid_request\", () => pm.expect(body.code).to.eql(\"invalid_request\"));",
                  "pm.test(\"details name body.types.0\", () => pm.expect((body.details || []).map((d) => d.path)).to.include(\"body.types.0\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/users.transactions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "users.transactions"
              ]
            },
            "description": "`users.transactions`: `types` accepts `DEPOSIT`, `DEPOSIT_REQUEST`, `DEPOSIT_CLAIM`, `DEPOSIT_CANCEL`, `REDEEM_REQUEST`, `REDEEM_CANCEL`, `WITHDRAW` and `WITHDRAW_INSTANT`.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"address\": \"{{walletAddress}}\",\n  \"types\": [\n    \"SWAP\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 Unknown transaction type",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/users.transactions",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "users.transactions"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"address\": \"{{walletAddress}}\",\n  \"types\": [\n    \"SWAP\"\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "9e700215-0cc9-4f43-ad68-86b0b57d110b"
                }
              ],
              "body": "{\n  \"error\": \"The request is not valid. See details.\",\n  \"code\": \"invalid_request\",\n  \"requestId\": \"9e700215-0cc9-4f43-ad68-86b0b57d110b\",\n  \"details\": [\n    {\n      \"path\": \"body.types.0\",\n      \"issue\": \"Invalid option: expected one of \\\"DEPOSIT\\\"|\\\"DEPOSIT_REQUEST\\\"|\\\"DEPOSIT_CLAIM\\\"|\\\"DEPOSIT_CANCEL\\\"|\\\"REDEEM_REQUEST\\\"|\\\"REDEEM_CANCEL\\\"|\\\"WITHDRAW\\\"|\\\"WITHDRAW_INSTANT\\\"\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "46d03662-3e4d-57e0-a3c1-2692d93a6a47",
          "name": "400 - limit above 100",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is invalid_request\", () => pm.expect(body.code).to.eql(\"invalid_request\"));",
                  "pm.test(\"details name body.limit\", () => pm.expect((body.details || []).map((d) => d.path)).to.include(\"body.limit\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/users.transactions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "users.transactions"
              ]
            },
            "description": "`users.transactions`: `limit` is 1 to 100 (default 50).",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"address\": \"{{walletAddress}}\",\n  \"limit\": 101\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 limit above 100",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/users.transactions",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "users.transactions"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"address\": \"{{walletAddress}}\",\n  \"limit\": 101\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "b4f59ce9-e671-4ab5-ba70-260fa0b9801c"
                }
              ],
              "body": "{\n  \"error\": \"The request is not valid. See details.\",\n  \"code\": \"invalid_request\",\n  \"requestId\": \"b4f59ce9-e671-4ab5-ba70-260fa0b9801c\",\n  \"details\": [\n    {\n      \"path\": \"body.limit\",\n      \"issue\": \"Too big: expected number to be <=100\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "d748355e-8a69-50f7-a6fb-ebef913fd886",
          "name": "400 - invalid cursor",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is invalid_cursor\", () => pm.expect(body.code).to.eql(\"invalid_cursor\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/users.transactions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "users.transactions"
              ]
            },
            "description": "`users.transactions`: cursors are signed: a changed cursor, or one that comes from a page with other `address`, `slug` or `types`, answers `invalid_cursor`. Start again from the first page.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"address\": \"{{walletAddress}}\",\n  \"cursor\": \"bm90LWEtY3Vyc29y\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 A cursor that does not decode, or that comes from other filters",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/users.transactions",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "users.transactions"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"address\": \"{{walletAddress}}\",\n  \"cursor\": \"bm90LWEtY3Vyc29y\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "3b8d5f1e-7a24-4c69-9e0b-6d2f8a4c1e75"
                }
              ],
              "body": "{\n  \"error\": \"The cursor is not valid. Start again from the first page.\",\n  \"code\": \"invalid_cursor\",\n  \"requestId\": \"3b8d5f1e-7a24-4c69-9e0b-6d2f8a4c1e75\"\n}"
            }
          ]
        },
        {
          "id": "3e7b54ac-c91c-5487-8eb5-b6ff54cdfeac",
          "name": "400 - transaction.quote with an unknown type",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is invalid_request\", () => pm.expect(body.code).to.eql(\"invalid_request\"));",
                  "pm.test(\"details name body.type\", () => pm.expect((body.details || []).map((d) => d.path)).to.include(\"body.type\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/transaction.quote",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "transaction.quote"
              ]
            },
            "description": "`transaction.quote`: `type` is `DEPOSIT` or `REDEEM_REQUEST`. A redeem request is the only way out of a vault.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"WITHDRAW\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 A type other than DEPOSIT or REDEEM_REQUEST",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.quote",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.quote"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"WITHDRAW\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "43bb59c2-0567-46ec-a325-b707654a797c"
                }
              ],
              "body": "{\n  \"error\": \"The request is not valid. See details.\",\n  \"code\": \"invalid_request\",\n  \"requestId\": \"43bb59c2-0567-46ec-a325-b707654a797c\",\n  \"details\": [\n    {\n      \"path\": \"body.type\",\n      \"issue\": \"must be \\\"DEPOSIT\\\" or \\\"REDEEM_REQUEST\\\"\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "e472c206-d2cb-5e59-bf45-bf4ba5513084",
          "name": "400 - transaction.quote without a slug",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is invalid_request\", () => pm.expect(body.code).to.eql(\"invalid_request\"));",
                  "pm.test(\"details name body.slug\", () => pm.expect((body.details || []).map((d) => d.path)).to.include(\"body.slug\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/transaction.quote",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "transaction.quote"
              ]
            },
            "description": "`transaction.quote`: the vault `slug` goes in the body, like every other action.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"amount\": \"{{depositAmount}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 No vault slug",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.quote",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.quote"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"amount\": \"{{depositAmount}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "287a5223-8edc-49b3-8a7b-fbc8ed9b9418"
                }
              ],
              "body": "{\n  \"error\": \"The request is not valid. See details.\",\n  \"code\": \"invalid_request\",\n  \"requestId\": \"287a5223-8edc-49b3-8a7b-fbc8ed9b9418\",\n  \"details\": [\n    {\n      \"path\": \"body.slug\",\n      \"issue\": \"Invalid input: expected string, received undefined\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "84bb66ed-15f4-5390-af15-6f21a898b3b9",
          "name": "400 - transaction.quote amount with decimals",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is invalid_request\", () => pm.expect(body.code).to.eql(\"invalid_request\"));",
                  "pm.test(\"details name body.amount\", () => pm.expect((body.details || []).map((d) => d.path)).to.include(\"body.amount\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/transaction.quote",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "transaction.quote"
              ]
            },
            "description": "`transaction.quote`: amounts are base-unit integer strings: `\"1000500000\"` is 1,000.5 USDC.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"1000.5\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 An amount with decimals",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.quote",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.quote"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"1000.5\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "3c8bc363-47df-409d-b361-81e5b1d10e2a"
                }
              ],
              "body": "{\n  \"error\": \"The request is not valid. See details.\",\n  \"code\": \"invalid_request\",\n  \"requestId\": \"3c8bc363-47df-409d-b361-81e5b1d10e2a\",\n  \"details\": [\n    {\n      \"path\": \"body.amount\",\n      \"issue\": \"must be a positive integer in base units, without sign, decimals, exponent or leading zeros\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "af8718b8-75a8-5ce0-af4a-7e68411f90c8",
          "name": "400 - transaction.quote deposit below the minimum",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is amount_below_minimum\", () => pm.expect(body.code).to.eql(\"amount_below_minimum\"));",
                  "pm.test(\"details name body.amount\", () => pm.expect((body.details || []).map((d) => d.path)).to.include(\"body.amount\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/transaction.quote",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "transaction.quote"
              ]
            },
            "description": "`transaction.quote`: a deposit must be at least 1 USDC (`\"1000000\"`). `details` gives the minimum.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"999999\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 Less than 1 USDC",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.quote",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.quote"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"999999\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "b033962d-4357-467f-827a-c7975aaa0a8a"
                }
              ],
              "body": "{\n  \"error\": \"The amount is below the vault minimum.\",\n  \"code\": \"amount_below_minimum\",\n  \"requestId\": \"b033962d-4357-467f-827a-c7975aaa0a8a\",\n  \"details\": [\n    {\n      \"path\": \"body.amount\",\n      \"issue\": \"must be at least 1000000 base units (1 USDC)\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "498d5fa5-07d6-5db7-b618-445e5119945e",
          "name": "400 - transaction.build without a sender",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is invalid_request\", () => pm.expect(body.code).to.eql(\"invalid_request\"));",
                  "pm.test(\"details name body.sender\", () => pm.expect((body.details || []).map((d) => d.path)).to.include(\"body.sender\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/transaction.build",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "transaction.build"
              ]
            },
            "description": "`transaction.build`: a build needs the `sender`, the wallet that signs and sends.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"REDEEM_REQUEST\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"shares\": \"{{redeemShares}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 No sender",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.build",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.build"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"REDEEM_REQUEST\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"shares\": \"{{redeemShares}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "54b94174-0f08-4598-bae6-23beb4699e87"
                }
              ],
              "body": "{\n  \"error\": \"The request is not valid. See details.\",\n  \"code\": \"invalid_request\",\n  \"requestId\": \"54b94174-0f08-4598-bae6-23beb4699e87\",\n  \"details\": [\n    {\n      \"path\": \"body.sender\",\n      \"issue\": \"Invalid input: expected string, received undefined\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "bfa39288-626f-5191-9508-1a1d3a59c10a",
          "name": "400 - transaction.build receiver is not the sender",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400 Bad Request\", () => pm.response.to.have.status(400));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is invalid_request\", () => pm.expect(body.code).to.eql(\"invalid_request\"));",
                  "pm.test(\"details name body.receiver\", () => pm.expect((body.details || []).map((d) => d.path)).to.include(\"body.receiver\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/transaction.build",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "transaction.build"
              ]
            },
            "description": "`transaction.build`: the shares of a deposit go to the sender: `receiver`, when sent, must equal `sender`.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\",\n  \"sender\": \"{{senderAddress}}\",\n  \"receiver\": \"0x000000000000000000000000000000000000dEaD\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "400 A receiver other than the sender",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/transaction.build",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "transaction.build"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"type\": \"DEPOSIT\",\n  \"slug\": \"{{vaultSlug}}\",\n  \"amount\": \"{{depositAmount}}\",\n  \"sender\": \"{{senderAddress}}\",\n  \"receiver\": \"0x000000000000000000000000000000000000dEaD\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Bad Request",
              "code": 400,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "da068048-1cf7-4506-9963-eb1943d65fa7"
                }
              ],
              "body": "{\n  \"error\": \"The request is not valid. See details.\",\n  \"code\": \"invalid_request\",\n  \"requestId\": \"da068048-1cf7-4506-9963-eb1943d65fa7\",\n  \"details\": [\n    {\n      \"path\": \"body.receiver\",\n      \"issue\": \"must equal sender\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "6053b1a5-fd27-5494-8dbf-872d3f1fdc86",
          "name": "404 - unknown vault",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"404 Not Found\", () => pm.response.to.have.status(404));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is vault_not_found\", () => pm.expect(body.code).to.eql(\"vault_not_found\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/vaults.get",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "vaults.get"
              ]
            },
            "description": "A slug that matches no vault.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"slug\": \"unknown-vault\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "404 No vault has this slug.",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/vaults.get",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "vaults.get"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"slug\": \"unknown-vault\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "3e515e1a-ad93-4506-81fc-aa47575c15f6"
                }
              ],
              "body": "{\n  \"error\": \"No vault exists with this slug.\",\n  \"code\": \"vault_not_found\",\n  \"requestId\": \"3e515e1a-ad93-4506-81fc-aa47575c15f6\"\n}"
            }
          ]
        },
        {
          "id": "5c2a3fb5-42bd-5fc7-b6f1-7f81b56a7f9c",
          "name": "404 - unknown action",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"404 Not Found\", () => pm.response.to.have.status(404));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is route_not_found\", () => pm.expect(body.code).to.eql(\"route_not_found\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/vaults.lists",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "vaults.lists"
              ]
            },
            "description": "An action that does not exist (here a typo of `vaults.list`). Without a valid key this is a 401 instead, so the API does not reveal its actions.",
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "404 The action does not exist.",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/vaults.lists",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "vaults.lists"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Not Found",
              "code": 404,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "e1e66de4-5d1b-5315-9677-58973996b0b8"
                }
              ],
              "body": "{\n  \"error\": \"This route does not exist.\",\n  \"code\": \"route_not_found\",\n  \"requestId\": \"e1e66de4-5d1b-5315-9677-58973996b0b8\"\n}"
            }
          ]
        },
        {
          "id": "9613dd4c-f96c-5af2-aaac-1ebeaa5a12b8",
          "name": "405 - GET instead of POST",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"405 Method Not Allowed\", () => pm.response.to.have.status(405));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is method_not_allowed\", () => pm.expect(body.code).to.eql(\"method_not_allowed\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/health.ping",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "health.ping"
              ]
            },
            "description": "Every action is POST. Any other method answers 405, before the key is checked."
          },
          "response": [
            {
              "name": "405 Use POST.",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/health.ping",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "health.ping"
                  ]
                }
              },
              "status": "Method Not Allowed",
              "code": 405,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "cffc2cd7-a82b-590f-b237-3181308a2524"
                }
              ],
              "body": "{\n  \"error\": \"This method is not allowed on this route.\",\n  \"code\": \"method_not_allowed\",\n  \"requestId\": \"cffc2cd7-a82b-590f-b237-3181308a2524\"\n}"
            }
          ]
        },
        {
          "id": "986e1d25-6fd3-5a97-bf94-eccc5f55324e",
          "name": "413 - body over 16 KiB",
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "// Pads the body past the 16 KiB limit.",
                  "pm.request.body.update(JSON.stringify({ padding: \"x\".repeat(17 * 1024) }));"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"413 Payload Too Large\", () => pm.response.to.have.status(413));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is payload_too_large\", () => pm.expect(body.code).to.eql(\"payload_too_large\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/health.ping",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "health.ping"
              ]
            },
            "description": "The pre-request script pads the body to 17 KiB. Bodies may be at most 16 KiB.",
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": [
            {
              "name": "413 The body is over 16 KiB.",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/health.ping",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "health.ping"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "status": "Payload Too Large",
              "code": 413,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "0c8e5a7d-3f21-4b96-a4d8-7e1b9c2f6a30"
                }
              ],
              "body": "{\n  \"error\": \"The request body is too large.\",\n  \"code\": \"payload_too_large\",\n  \"requestId\": \"0c8e5a7d-3f21-4b96-a4d8-7e1b9c2f6a30\"\n}"
            }
          ]
        },
        {
          "id": "3117c45b-6936-52cd-bc8b-ebfdb5f4bffe",
          "name": "415 - not application/json",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"415 Unsupported Media Type\", () => pm.response.to.have.status(415));",
                  "const body = pm.response.json();",
                  "pm.test(\"code is unsupported_media_type\", () => pm.expect(body.code).to.eql(\"unsupported_media_type\"));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "text/plain",
                "type": "text"
              },
              {
                "key": "x-request-id",
                "value": "{{$guid}}",
                "type": "text",
                "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/health.ping",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "health.ping"
              ]
            },
            "description": "The body must be sent with `Content-Type: application/json`.",
            "body": {
              "mode": "raw",
              "raw": "{}",
              "options": {
                "raw": {
                  "language": "text"
                }
              }
            }
          },
          "response": [
            {
              "name": "415 The body was not sent as application/json.",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "text/plain",
                    "type": "text"
                  },
                  {
                    "key": "x-request-id",
                    "value": "{{$guid}}",
                    "type": "text",
                    "description": "Optional. Your id for this request (1 to 128 letters, digits, `.`, `_`, `:` or `-`). It comes back in the `x-request-id` response header and in error bodies. Quote it when you contact Kamui. The collection sends a new UUID each time."
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/health.ping",
                  "host": [
                    "{{baseUrl}}"
                  ],
                  "path": [
                    "health.ping"
                  ]
                },
                "body": {
                  "mode": "raw",
                  "raw": "{}",
                  "options": {
                    "raw": {
                      "language": "text"
                    }
                  }
                }
              },
              "status": "Unsupported Media Type",
              "code": 415,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json; charset=utf-8"
                },
                {
                  "key": "Cache-Control",
                  "value": "no-store"
                },
                {
                  "key": "X-Content-Type-Options",
                  "value": "nosniff"
                },
                {
                  "key": "x-request-id",
                  "value": "9b4f6e2a-1c7d-4a85-8e3f-5d0a2b6c9e17"
                }
              ],
              "body": "{\n  \"error\": \"Send the request body as application/json.\",\n  \"code\": \"unsupported_media_type\",\n  \"requestId\": \"9b4f6e2a-1c7d-4a85-8e3f-5d0a2b6c9e17\"\n}"
            }
          ]
        }
      ]
    }
  ],
  "auth": {
    "type": "apikey",
    "apikey": [
      {
        "key": "key",
        "value": "x-partner-api-key",
        "type": "string"
      },
      {
        "key": "value",
        "value": "{{partnerApiKey}}",
        "type": "string"
      },
      {
        "key": "in",
        "value": "header",
        "type": "string"
      }
    ]
  },
  "event": [
    {
      "listen": "test",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// Runs after every request in this collection.",
          "pm.test(\"responds with JSON\", () => pm.expect(pm.response.headers.get(\"Content-Type\") || \"\").to.include(\"application/json\"));",
          "pm.test(\"is never cached (Cache-Control: no-store)\", () => pm.expect(pm.response.headers.get(\"Cache-Control\")).to.eql(\"no-store\"));",
          "pm.test(\"has an x-request-id header\", () => pm.expect(pm.response.headers.get(\"x-request-id\")).to.be.a(\"string\"));",
          "let body;",
          "try { body = pm.response.json(); } catch (error) { body = undefined; }",
          "if (body && pm.response.code < 400) {",
          "  pm.test(\"success envelope { data, asOf }\", () => {",
          "    pm.expect(body).to.have.property(\"data\");",
          "    pm.expect(body.asOf).to.be.a(\"number\");",
          "  });",
          "} else if (body) {",
          "  pm.test(\"error envelope { error, code, requestId }\", () => {",
          "    pm.expect(body.error).to.be.a(\"string\");",
          "    pm.expect(body.code).to.be.a(\"string\");",
          "    pm.expect(body.requestId).to.eql(pm.response.headers.get(\"x-request-id\"));",
          "  });",
          "  // The Errors folder's \"401 - ...\" requests expect the 401.",
          "  if (pm.response.code === 401 && !pm.info.requestName.startsWith(\"401 - \")) {",
          "    const hint = pm.variables.get(\"partnerApiKey\")",
          "      ? \"the key was rejected: check it is the full key, issued for this baseUrl, and not revoked or expired\"",
          "      : \"partnerApiKey is empty: select the environment and paste the key into partnerApiKey\";",
          "    pm.test(`API key accepted (${hint})`, () => pm.expect(pm.response.code).to.not.eql(401));",
          "  }",
          "  // The Transactions requests need transaction building, which Kamui enables per API client.",
          "  if (body.code === \"actions_not_enabled\") {",
          "    pm.test(\"transaction building enabled for this API client (ask Kamui to enable it)\", () => pm.expect(body.code).to.not.eql(\"actions_not_enabled\"));",
          "  } else if (body.code === \"actions_disabled\") {",
          "    pm.test(\"transaction building switched on (Kamui has switched it off for now; the read actions still answer)\", () => pm.expect(body.code).to.not.eql(\"actions_disabled\"));",
          "  }",
          "  // Every API client has per-minute limits: one for the read actions, one for the transaction actions.",
          "  if (pm.response.code === 429) {",
          "    const wait = pm.response.headers.get(\"Retry-After\") || \"?\";",
          "    const policy = pm.response.headers.get(\"RateLimit-Policy\") || \"not sent\";",
          "    pm.test(`rate limit not exceeded (wait Retry-After=${wait}s; your limit: ${policy}; defaults per client: reads 120/min, transaction actions 20/min)`, () => pm.expect(pm.response.code).to.not.eql(429));",
          "  }",
          "}"
        ]
      }
    }
  ],
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://api.kamui.finance/functions/v1/external-api",
      "type": "string",
      "description": "The API base URL. Every action is POST {{baseUrl}}/<action>."
    },
    {
      "key": "partnerApiKey",
      "value": "",
      "type": "string",
      "description": "Your API key (kmi_<id>_<secret>). Prefer the environment's secret variable. Put it in the Current value only."
    },
    {
      "key": "vaultSlug",
      "value": "stable-vault",
      "type": "string",
      "description": "stable-vault, balanced-vault or boosted-vault."
    },
    {
      "key": "walletAddress",
      "value": "0x1111111111111111111111111111111111111111",
      "type": "string",
      "description": "The wallet for users.positions and users.transactions (0x + 40 hex characters)."
    },
    {
      "key": "senderAddress",
      "value": "0x1111111111111111111111111111111111111111",
      "type": "string",
      "description": "The wallet that signs and sends the transactions of transaction.build (0x + 40 hex characters). The default is illustrative and holds nothing."
    },
    {
      "key": "depositAmount",
      "value": "1000000000",
      "type": "string",
      "description": "USDC to deposit, in base units (6 decimals): 1000000000 is 1,000 USDC. At least 1000000 (1 USDC)."
    },
    {
      "key": "redeemShares",
      "value": "250000000000000000000",
      "type": "string",
      "description": "Vault shares to put in a redeem request, in base units (18 decimals): 250000000000000000000 is 250 shares."
    },
    {
      "key": "historyFrom",
      "value": "",
      "type": "string",
      "description": "Unix seconds for vaults.history - custom range. Empty: 30 days before historyTo."
    },
    {
      "key": "historyTo",
      "value": "",
      "type": "string",
      "description": "Unix seconds for vaults.history - custom range. Empty: the start of today (UTC)."
    },
    {
      "key": "transactionsCursor",
      "value": "",
      "type": "string",
      "description": "Set by the users.transactions scripts from nextCursor."
    },
    {
      "key": "transactionsSnapshotAt",
      "value": "",
      "type": "string",
      "description": "Set by users.transactions - first page; next page checks it stays fixed."
    }
  ]
}
