Idempotency
Networks fail. If a write request times out, you can't know whether DOOLAE did the work. Send an Idempotency-Key header, and retrying can never do it twice.
curl https://api.doolae.online/v1/bills \
-H "Authorization: Bearer $DOOLAE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 9a8f3c1e-2b4d-4e6f-8a1b-3c5d7e9f0a2b" \
-d '{"room_id": "room_…", "month": "2026-10"}'
Every POST, PATCH and DELETE endpoint accepts it. Use a new random value (a UUID) for each operation, and the same value when you retry that operation.
What happens
| You send | You get |
|---|---|
| A new key | The request runs. Its response is stored for 24 hours. |
| The same key and the same request again | The stored response, unchanged, with Idempotent-Replayed: true. Nothing runs again. |
| The same key while the first request is still running | 409 idempotency_in_progress. Retry after a second. |
| The same key with a different body, method or path | 422 idempotency_key_reused. |
- Keys are scoped to your application and the account. Two applications, or two accounts, can't collide.
- Responses
2xxto4xxare stored. A5xxis not, so you can simply retry. - If a request stopped half-way on DOOLAE's side, a retry after about 60 seconds runs it again. That is safe, because every write is all-or-nothing.
- A key may be up to 255 printable ASCII characters (
400 invalid_idempotency_keyotherwise).
Built-in protection
Even without a key, some writes can't be duplicated:
| Write | What stops a duplicate |
|---|---|
POST /v1/meter-readings |
One reading per room and month (409 resource_exists with the existing ID). |
POST /v1/bills |
One bill per room and month (409 resource_exists). |
POST /v1/rooms/{room_id}/tenant |
One tenant per room (409 room_occupied). |
POST /v1/properties/{property_id}/rooms |
Room numbers are unique within a property (409 room_number_taken). |
| LINE messages | Each message is delivered once even if DOOLAE retries it. |
POST /v1/notifications, POST /v1/messages and POST /v1/properties have no such natural key: always send an Idempotency-Key with them.