API
Know What’s Due answers one question: what important things in your life need attention again, and when. A passport that expires, a registration that renews, a filter that needs changing — a name, a date, and how often it comes round.
This API exists so an AI agent can keep that list on your behalf: add to it, tell you what is due, and tick things off. The machine-readable description is at /openapi.json.
Authentication
OAuth 2.1 authorization code flow with PKCE. The authorization server is Supabase Auth; Know What’s Due hosts the consent screen you approve on.
- The app sends you to Supabase’s authorize endpoint with a PKCE challenge.
- Supabase sends you to the Know What’s Due consent screen, which names the app and exactly what it will be able to do.
- You approve or cancel. Either way you are sent back to the app.
- On approval the app exchanges its code for an access token and presents it as
Authorization: Bearer <token>.
Clients are registered in advance and redirect URIs must match exactly. Dynamic client registration is not enabled, so an app nobody registered cannot reach the consent screen at all.
Access is scoped to one person
Every request acts as exactly one account.Which account is taken from the access token. There is no parameter for it — not in a path, a query or a body — so there is nothing to change in order to reach somebody else’s data.
That is enforced by Postgres row level security, not by this API. Every query runs as the token’s own user and the database refuses rows belonging to anyone else, so the guarantee holds even for a caller that bypasses these endpoints and speaks to the data layer directly. This documentation describes the convenient path, not the boundary.
A connection is granted two capabilities when you approve it: read_obligations and write_obligations. These are this product’s own vocabulary, not OAuth scopes — no client can request one, and nothing in a token carries one.
Dates
Dates are plain YYYY-MM-DD in yourtime zone — never the caller’s, never UTC.
Do not compute due dates yourself. Every obligation already carries due_in_days, overdue and needs_attention, and every list carries the today and timezone they were judged against. Only the server knows which day it is for you.
Operations
Base URL /api/v1. Every response is either { "data": … } or { "error": { "code", "message" } }. Branch on code; the message is written for a person and may be reworded.
An obligation is name + next_due_date, optionally a recurrence, optionally a reminder window, optionally a note. Two examples, end to end:
// "Remember that my passport expires October 1, 2031."
POST /obligations
{ "name": "Passport", "next_due_date": "2031-10-01" }
// "My furnace filter needs changing December 20, then every 3 months."
POST /obligations
{ "name": "Furnace filter", "next_due_date": "2026-12-20",
"recurrence_value": 3, "recurrence_unit": "months" }- GET /obligations
- What you are tracking, soonest first. Defaults to active obligations. Filters below.
- POST /obligations
- Add one. Needs only
nameandnext_due_date. Addrecurrence_valueandrecurrence_unittogether if it repeats. - PATCH /obligations/{id}
- Change one. Omitted fields are left alone. Send both
recurrence_valueandrecurrence_unitasnullto stop something repeating. - DELETE /obligations/{id}
- Archives — it does not permanently delete. The status becomes
archivedand the record stays. No operation in this API removes anything for good; only you can, from Know What’s Due itself. - POST /obligations/{id}/complete
- Mark it done. Optional body
{ "completed_on": … }, which may be backdated but not postdated.
Filters on GET /obligations
- status
active(the default),completed,archived, orall. Anything else is refused rather than ignored.- due_before
YYYY-MM-DD. Due on or before this date, inclusive. This is how you ask for what is coming up.- overdue
trueorfalse. Strictly before today — something due today is not overdue.- limit
- 1 to 200. Defaults to 100.
Completing something
This is the part worth reading twice, because it is where an agent is most likely to guess wrong.
What completion does is decided by exactly one thing: whether the obligation has a recurrence. There is no category field and nothing to classify.
- If it repeats, the next due date moves forward one interval from the day it was completed, not from the day it was due, and it stays active. A filter due September 1, changed September 19, on a three month cycle, is next due December 19.
- If it does not repeat, the due date stays where it is and the status becomes
completed.
The response tells you which happened in repeated, so there is no need to work it out by comparing dates.
An interval is a whole number and a unit: days, weeks, months, years. Send both together, or neither.
Dates, not documents
Know What’s Due is designed to hold dates and simple descriptive metadata about an obligation: a name, a type, a due date, how often it comes round, and an optional short note.
It is not a document vault. There is no field for a document scan, a passport or licence number, an account or policy number, a card number, or any similar sensitive document contents — and none should be written into name or notes, which are capped at 120 and 500 characters and are meant for things like “Passport” and “renew online, takes 6 weeks”.
The intended shape of a record is “Passport — expires June 3, 2028”. That is enough to track an obligation, and it is all Know What’s Due asks for.
Full schemas, error codes and the OAuth endpoints are in /openapi.json.