{
  "info": {
    "name": "Stablevoy API",
    "description": "Set apiKey (from the dashboard) in the collection variables or the Stablevoy environment. accessToken is only for the merchant session endpoints. Reference: https://stablevoy.com/docs/api/",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{apiKey}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://api.stablevoy.com"
    },
    {
      "key": "apiKey",
      "value": ""
    },
    {
      "key": "accessToken",
      "value": ""
    }
  ],
  "item": [
    {
      "name": "Invoices",
      "description": "Create invoices and read their status and payments. The main thing a shop integration does.",
      "item": [
        {
          "name": "Create an invoice",
          "request": {
            "method": "POST",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{apiKey}}",
                  "type": "string"
                }
              ]
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "order-1042",
                "disabled": true,
                "description": "Makes retries safe: the same key and body return the first invoice. Printable ASCII, up to 255 characters."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/invoices",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "invoices"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"amountUsdCents\": 1999,\n  \"externalReference\": \"order-1042\",\n  \"returnUrl\": \"https://shop.example/checkout/order-received/1042/\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Creates an invoice for the store the API key belongs to and returns its deposit addresses and the hosted payment page (checkoutUrl). Send the buyer to checkoutUrl, then wait for the webhook.\n\nSend an **Idempotency-Key** header (printable ASCII, up to 255 characters, e.g. your order id) to retry safely: the same key with the same body returns the first invoice with replayed: true; the same key with a different body is a conflict."
          }
        },
        {
          "name": "List invoices",
          "request": {
            "method": "GET",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{apiKey}}",
                  "type": "string"
                }
              ]
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/invoices?limit=20",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "invoices"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "20",
                  "disabled": false,
                  "description": "Page size, 1 to 100."
                },
                {
                  "key": "cursor",
                  "value": "",
                  "disabled": true,
                  "description": "nextCursor from the previous page."
                },
                {
                  "key": "status",
                  "value": "",
                  "disabled": true,
                  "description": "Only invoices in this status."
                }
              ]
            },
            "description": "Invoices of the API key's store, newest first, optionally filtered by status. Pages are cursor based: pass nextCursor as cursor until it is null."
          }
        },
        {
          "name": "Create an invoice for a store (dashboard)",
          "request": {
            "method": "POST",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "order-1042",
                "disabled": true,
                "description": "Makes retries safe: the same key and body return the first invoice. Printable ASCII, up to 255 characters."
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/stores/:storeId/invoices",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "stores",
                ":storeId",
                "invoices"
              ],
              "variable": [
                {
                  "key": "storeId",
                  "value": "",
                  "description": "Store id (UUID)."
                }
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"amountUsdCents\": 1999,\n  \"externalReference\": null,\n  \"returnUrl\": null\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "The same as POST /v1/invoices, for a signed-in merchant choosing the store, e.g. payment links made in the dashboard. Supports Idempotency-Key the same way."
          }
        },
        {
          "name": "List invoices of a store (dashboard)",
          "request": {
            "method": "GET",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/stores/:storeId/invoices?limit=20",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "stores",
                ":storeId",
                "invoices"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "20",
                  "disabled": false,
                  "description": "Page size, 1 to 100."
                },
                {
                  "key": "cursor",
                  "value": "",
                  "disabled": true,
                  "description": "nextCursor from the previous page."
                },
                {
                  "key": "status",
                  "value": "",
                  "disabled": true,
                  "description": "Only invoices in this status."
                }
              ],
              "variable": [
                {
                  "key": "storeId",
                  "value": "",
                  "description": "Store id (UUID)."
                }
              ]
            },
            "description": "The same as GET /v1/invoices, for a signed-in merchant choosing the store."
          }
        },
        {
          "name": "Get an invoice",
          "request": {
            "method": "GET",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{apiKey}}",
                  "type": "string"
                }
              ]
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/invoices/:invoiceId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "invoices",
                ":invoiceId"
              ],
              "variable": [
                {
                  "key": "invoiceId",
                  "value": "",
                  "description": "Invoice id (UUID)."
                }
              ]
            },
            "description": "One invoice with its deposit addresses and every payment received. Use it to double-check a webhook before fulfilling an order."
          }
        }
      ]
    },
    {
      "name": "Checkout",
      "description": "Public data behind the hosted payment page.",
      "item": [
        {
          "name": "Payment page data",
          "request": {
            "method": "GET",
            "auth": {
              "type": "noauth"
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/checkout/invoices/:invoiceId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "checkout",
                "invoices",
                ":invoiceId"
              ],
              "variable": [
                {
                  "key": "invoiceId",
                  "value": "",
                  "description": "Invoice id (UUID)."
                }
              ]
            },
            "description": "Public data of the hosted payment page, by the unguessable invoice id: amount per token and network, deposit addresses and what the page needs to recompute each address itself and refuse a tampered one. Exposes nothing private."
          }
        }
      ]
    },
    {
      "name": "Stores",
      "description": "Stores with their networks, limits, website and webhook.",
      "item": [
        {
          "name": "List stores",
          "request": {
            "method": "GET",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/stores",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "stores"
              ]
            },
            "description": "Every store of the signed-in merchant."
          }
        },
        {
          "name": "Create a store",
          "request": {
            "method": "POST",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/stores",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "stores"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"My Shop\",\n  \"enabledNetworks\": [\n    \"base\",\n    \"arbitrum\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "A store has its own API keys, webhook, networks and invoice limits. An account may have a limited number of stores (maxStores in GET /v1/me)."
          }
        },
        {
          "name": "The API key's store",
          "request": {
            "method": "GET",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{apiKey}}",
                  "type": "string"
                }
              ]
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/store",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "store"
              ]
            },
            "description": "The store the API key belongs to. Plugins call it to check the key and read the limits and enabled networks."
          }
        },
        {
          "name": "Get a store",
          "request": {
            "method": "GET",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{apiKey}}",
                  "type": "string"
                }
              ]
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/stores/:storeId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "stores",
                ":storeId"
              ],
              "variable": [
                {
                  "key": "storeId",
                  "value": "",
                  "description": "Store id (UUID)."
                }
              ]
            },
            "description": "One store, by a signed-in merchant or with that store's API key."
          }
        },
        {
          "name": "Update a store",
          "request": {
            "method": "PATCH",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/stores/:storeId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "stores",
                ":storeId"
              ],
              "variable": [
                {
                  "key": "storeId",
                  "value": "",
                  "description": "Store id (UUID)."
                }
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"webhookUrl\": \"https://shop.example/wp-json/stablevoy/v1/webhook\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Changes only the fields you send; null clears an optional field. When a webhook URL is set for the first time the response carries webhookSecret, once: store it to verify webhook signatures."
          }
        }
      ]
    },
    {
      "name": "API keys",
      "description": "Keys for server-to-server calls, one store each.",
      "item": [
        {
          "name": "List API keys",
          "request": {
            "method": "GET",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/stores/:storeId/api-keys",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "stores",
                ":storeId",
                "api-keys"
              ],
              "variable": [
                {
                  "key": "storeId",
                  "value": "",
                  "description": "Store id (UUID)."
                }
              ]
            },
            "description": "Every key of the store, active and revoked, with its prefix and last use. Secrets are never returned again."
          }
        },
        {
          "name": "Create an API key",
          "request": {
            "method": "POST",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/stores/:storeId/api-keys",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "stores",
                ":storeId",
                "api-keys"
              ],
              "variable": [
                {
                  "key": "storeId",
                  "value": "",
                  "description": "Store id (UUID)."
                }
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"WooCommerce\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Creates a key for server-to-server calls (plugins, your backend). The full key is in this response only: store it. Never put it in a browser or an app."
          }
        },
        {
          "name": "Revoke an API key",
          "request": {
            "method": "DELETE",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/stores/:storeId/api-keys/:keyId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "stores",
                ":storeId",
                "api-keys",
                ":keyId"
              ],
              "variable": [
                {
                  "key": "storeId",
                  "value": "",
                  "description": "Store id (UUID)."
                },
                {
                  "key": "keyId",
                  "value": "",
                  "description": "API key id (UUID)."
                }
              ]
            },
            "description": "The key stops working at once. Revoking is permanent; create a new key instead of reusing it."
          }
        }
      ]
    },
    {
      "name": "Webhooks",
      "description": "Signing secret, test events, delivery history and redelivery.",
      "item": [
        {
          "name": "Rotate the webhook secret",
          "request": {
            "method": "POST",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/stores/:storeId/webhook-secret/rotate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "stores",
                ":storeId",
                "webhook-secret",
                "rotate"
              ],
              "variable": [
                {
                  "key": "storeId",
                  "value": "",
                  "description": "Store id (UUID)."
                }
              ]
            },
            "description": "Makes a new signing secret and returns it once. The old one stops working at once, so update your shop right away."
          }
        },
        {
          "name": "Send a test webhook",
          "request": {
            "method": "POST",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/stores/:storeId/webhook/test",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "stores",
                ":storeId",
                "webhook",
                "test"
              ],
              "variable": [
                {
                  "key": "storeId",
                  "value": "",
                  "description": "Store id (UUID)."
                }
              ]
            },
            "description": "Queues a webhook.test event that goes through the real delivery path (signature, retries). Check its delivery with the events endpoints."
          }
        },
        {
          "name": "List webhook events",
          "request": {
            "method": "GET",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/stores/:storeId/webhook-events?limit=20",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "stores",
                ":storeId",
                "webhook-events"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "20",
                  "disabled": false,
                  "description": "Page size, 1 to 100."
                },
                {
                  "key": "cursor",
                  "value": "",
                  "disabled": true,
                  "description": "nextCursor from the previous page."
                }
              ],
              "variable": [
                {
                  "key": "storeId",
                  "value": "",
                  "description": "Store id (UUID)."
                }
              ]
            },
            "description": "Events of the store with their delivery status, newest first, cursor paged."
          }
        },
        {
          "name": "Get a webhook event",
          "request": {
            "method": "GET",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/stores/:storeId/webhook-events/:eventId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "stores",
                ":storeId",
                "webhook-events",
                ":eventId"
              ],
              "variable": [
                {
                  "key": "storeId",
                  "value": "",
                  "description": "Store id (UUID)."
                },
                {
                  "key": "eventId",
                  "value": "",
                  "description": "Webhook event id (UUID)."
                }
              ]
            },
            "description": "One event with every delivery attempt: the status your endpoint answered, the error and how long it took."
          }
        },
        {
          "name": "Redeliver a webhook event",
          "request": {
            "method": "POST",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/stores/:storeId/webhook-events/:eventId/redeliver",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "stores",
                ":storeId",
                "webhook-events",
                ":eventId",
                "redeliver"
              ],
              "variable": [
                {
                  "key": "storeId",
                  "value": "",
                  "description": "Store id (UUID)."
                },
                {
                  "key": "eventId",
                  "value": "",
                  "description": "Webhook event id (UUID)."
                }
              ]
            },
            "description": "Queues the event for delivery again, for example after fixing your endpoint. Your handler should ignore events it has already processed (by event id)."
          }
        }
      ]
    },
    {
      "name": "Account",
      "description": "The signed-in merchant, setup progress and the payout wallet.",
      "item": [
        {
          "name": "Current account",
          "request": {
            "method": "GET",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/me",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "me"
              ]
            },
            "description": "The signed-in merchant: login wallet, payout wallet and how many stores the account may have."
          }
        },
        {
          "name": "Setup progress",
          "request": {
            "method": "GET",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/me/onboarding",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "me",
                "onboarding"
              ]
            },
            "description": "Which setup steps are done on the way to a first paid order: payout wallet, store, a key or payment link, webhook, first payment."
          }
        },
        {
          "name": "Start a payout wallet change",
          "request": {
            "method": "POST",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/me/payout-address/challenge",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "me",
                "payout-address",
                "challenge"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"payoutAddress\": \"0x5cC5bc5CC5bC5CC5bC5cc5bC5cC5bc5cc5Bc5cc5\",\n  \"chainId\": 8453\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Step 1: returns the message the login wallet must sign to approve the new payout wallet. The address must be EIP-55 checksummed so a typo cannot slip through."
          }
        },
        {
          "name": "Confirm a payout wallet change",
          "request": {
            "method": "POST",
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{accessToken}}",
                  "type": "string"
                }
              ]
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/me/payout-address/confirm",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "me",
                "payout-address",
                "confirm"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"payoutAddress\": \"0x5cC5bc5CC5bC5CC5bC5cc5bC5cC5bc5cc5Bc5cc5\",\n  \"challengeId\": \"7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d\",\n  \"signature\": \"0xababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Step 2: send the signature. The new wallet applies to invoices created from now on; existing invoices keep the wallet they were created with."
          }
        }
      ]
    },
    {
      "name": "Auth",
      "description": "Sign-In with Ethereum and sessions for the dashboard and apps.",
      "item": [
        {
          "name": "Start sign-in",
          "request": {
            "method": "POST",
            "auth": {
              "type": "noauth"
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/auth/siwe/challenge",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "auth",
                "siwe",
                "challenge"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"address\": \"0x5cC5bc5CC5bC5CC5bC5cc5bC5cC5bc5cc5Bc5cc5\",\n  \"chainId\": 8453\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Step 1 of Sign-In with Ethereum: returns a server-built EIP-4361 message for the wallet to sign. It is valid for a few minutes and only once."
          }
        },
        {
          "name": "Finish sign-in",
          "request": {
            "method": "POST",
            "auth": {
              "type": "noauth"
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/auth/siwe/verify",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "auth",
                "siwe",
                "verify"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"challengeId\": \"7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d\",\n  \"signature\": \"0xababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab\",\n  \"clientKind\": \"mobile\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Step 2: send the signature of the challenge message. Browsers (clientKind web) get httpOnly session cookies and only the expiry in the body; apps (mobile, other) get the access and refresh tokens in the body."
          }
        },
        {
          "name": "Refresh the session",
          "request": {
            "method": "POST",
            "auth": {
              "type": "noauth"
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/auth/refresh",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "auth",
                "refresh"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"refreshToken\": \"rt_9f8e7d6c5b4a39281706f5e4d3c2b1a0\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Exchanges the refresh token (cookie for browsers, body for apps) for a new pair. Each refresh token works once: reusing an old one signs out every session of that login."
          }
        },
        {
          "name": "Sign out",
          "request": {
            "method": "POST",
            "auth": {
              "type": "noauth"
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/auth/logout",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "auth",
                "logout"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"refreshToken\": \"rt_9f8e7d6c5b4a39281706f5e4d3c2b1a0\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Revokes the session of the refresh token and clears the browser cookies."
          }
        }
      ]
    },
    {
      "name": "System",
      "description": "Health, limits, pricing, networks, this document and the contact form.",
      "item": [
        {
          "name": "Service health",
          "request": {
            "method": "GET",
            "auth": {
              "type": "noauth"
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/health",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "health"
              ]
            },
            "description": "State of every network watcher and background component. Answers HTTP 503 with the same body when anything is degraded, so uptime monitors alert."
          }
        },
        {
          "name": "Platform invoice limits",
          "request": {
            "method": "GET",
            "auth": {
              "type": "noauth"
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/limits",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "limits"
              ]
            },
            "description": "The platform minimum and cap per invoice. Store limits must fit inside them."
          }
        },
        {
          "name": "Pricing",
          "request": {
            "method": "GET",
            "auth": {
              "type": "noauth"
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/pricing",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "pricing"
              ]
            },
            "description": "The one-time free volume per payout wallet, the fee above it in basis points and the cap the contract enforces."
          }
        },
        {
          "name": "Networks and tokens",
          "request": {
            "method": "GET",
            "auth": {
              "type": "noauth"
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/networks",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "networks"
              ]
            },
            "description": "Networks and stablecoins Stablevoy accepts, with the contract addresses on each, so you can verify them on the block explorer."
          }
        },
        {
          "name": "Error catalog",
          "request": {
            "method": "GET",
            "auth": {
              "type": "noauth"
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/errors",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "errors"
              ]
            },
            "description": "Every error code the API can answer, grouped, with its HTTP status, what it means and what to do. The same text is on https://stablevoy.com/docs/api/errors/."
          }
        },
        {
          "name": "OpenAPI document",
          "request": {
            "method": "GET",
            "auth": {
              "type": "noauth"
            },
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/openapi.json",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "openapi.json"
              ]
            },
            "description": "This API description in OpenAPI 3.1. Import the URL into Postman, Insomnia, Bruno or Swagger UI."
          }
        },
        {
          "name": "Contact the team",
          "request": {
            "method": "POST",
            "auth": {
              "type": "noauth"
            },
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/contact",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "contact"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Ann\",\n  \"email\": \"ann@shop.example\",\n  \"topic\": \"limits\",\n  \"message\": \"Please raise my store limit to twenty stores.\",\n  \"page\": \"/app/\",\n  \"turnstileToken\": \"XXXX.DUMMY.TOKEN.XXXX\",\n  \"website\": \"\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "description": "Used by the contact form on the site. Needs a Cloudflare Turnstile token from the page, so it is not meant for scripts. Limited to 5 messages per hour per IP."
          }
        }
      ]
    }
  ]
}
