> ## Documentation Index
> Fetch the complete documentation index at: https://docs.saasybill.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Requests and responses

> Formats, headers and conventions that apply to every endpoint

Every endpoint follows the same conventions. Learn them once and each endpoint behaves as you expect.

***

## Versioning

The version is in the path: `/api/v1`. Adding a field or an endpoint is not a breaking change and does not create a new version. A breaking change ships as `/v2`.

<Warning>
  Write your client to ignore response fields it doesn't recognise. New fields will appear in v1 responses over time.
</Warning>

***

## Data formats

| Type | Format | Example |
| - | - | - |
| Keys | `snake_case` | `invoice_reference` |
| Object type | Every object has an `object` field naming its type. | `"object": "subscription"` |
| Ids | Opaque strings. Store them as strings and don't parse them. | `"9d4e2b7a-13c5-4f8e-b6a0-2e1d7c9f5b33"` |
| Money | A decimal string with four decimal places. Never a number. | `"19.9900"` |
| Percentages | A decimal string with two decimal places. | `"10.00"` |
| Timestamps | ISO 8601, in UTC. | `"2026-09-30T04:12:00.000Z"` |
| Calendar dates | `YYYY-MM-DD`, in the subscription's own timezone. | `"2026-10-30"` |
| Enumerations | Lower case. | `"awaiting_approval"` |
| Empty values | `null`. Fields are present even when empty. | `"end_date": null` |

<Info>
  Parse money as a decimal type, not a floating-point number. `"19.9900"` is exact. `19.99` may not be.
</Info>

### Sending money and percentages

Fields that take an amount accept a decimal string or a number, with at most two decimal places. Prefer a string.

```json theme={null}
{ "flat_fee_price": "2400.00", "discount_percent": "10" }
```

### Sending dates

Dates are `YYYY-MM-DD`, read in the organisation's timezone. If you omit `start_date` when creating a subscription, it defaults to today in that timezone. Retrieve the timezone from [the organisation](/api-reference/organisation/retrieve-the-organisation).

***

## Request bodies

Send JSON with `Content-Type: application/json`. Bodies can be up to 100,000 characters.

The API rejects fields it doesn't know. A misspelt `discount_precent` would otherwise be ignored, and the subscription would be created with no discount. The error names the field.

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_parameter",
    "message": "`discount_precent` is not a field this endpoint accepts.",
    "param": "discount_precent",
    "request_id": "req_4f1a9c2e7b8d3a605e1c9f02"
  }
}
```

***

## Response headers

Every response includes these headers.

| Header | Description |
| - | - |
| `Request-Id` | A unique id for the request, such as `req_4f1a9c2e7b8d3a605e1c9f02`. The same id appears in error bodies and in the request log. Quote it when you contact support. |
| `RateLimit-Limit` | Requests allowed per minute for this key. See [Rate limits](/api-reference/rate-limits). |
| `RateLimit-Remaining` | Requests left in the current window. |
| `RateLimit-Reset` | Seconds until the oldest counted request stops counting. |
| `Idempotent-Replayed` | `true` when the response is a stored answer to a repeated request. See [Idempotency](/api-reference/idempotency). |
| `Retry-After` | Seconds to wait before trying again. Sent with `429` and with `409 request_in_progress`. |

Responses are never cached: they carry `Cache-Control: no-store`.

***

## Request log

Saasybill keeps a log of every authenticated request for 30 days. Find it under **Developer Settings**, then **Logs**. Each entry records the key, method, path, status, duration, request id and idempotency key.

The log never holds request or response bodies, because they carry customer data. It also records the path only, without the query string, which can carry a customer's email address.

***

## Where to next

<CardGroup cols={3}>
  <Card title="Pagination" icon="list" href="/api-reference/pagination">
    Page through lists.
  </Card>

  <Card title="Errors" icon="triangle-exclamation" href="/api-reference/errors">
    Handle failures.
  </Card>

  <Card title="Idempotency" icon="rotate" href="/api-reference/idempotency">
    Retry writes safely.
  </Card>
</CardGroup>
