Atrict exposes a JSON API for kids, memories, photos, families, permissions, and invites. Authenticate with an OAuth bearer token issued by the token endpoint, then call the API directly or experiment with it in the in-browser Swagger UI.
Click "Create API client", name it, pick scopes, confirm with step-up.
Copy the client ID and client secret once — we don't store the plaintext.
OAuth flow
Atrict supports the client_credentials grant for machine-to-machine access. Exchange your client_id + client_secret at /api/oauth/token to receive a short-lived JWT bearer token (default TTL: 15 minutes). Send the token in the Authorization header on every API request.
1Your script holds credentials
Client ID + secret stored in your environment, never in source control.
2POST /api/oauth/token
grant_type=client_credentials over HTTPS with HTTP Basic auth.
3Get a Bearer token
JWT (HS256), 15-minute TTL. Cache it; don't request a new one per call.
4Call /api/…
Send Authorization: Bearer <token>. Re-exchange credentials when the token expires.
List endpoints return a PageResult<T> envelope — { items, nextCursor }. To fetch the next page, pass ?cursor=<nextCursor>. When nextCursor is null, you've reached the end. Cursors are opaque base64-encoded values; don't decode or generate them yourself.
Errors
Errors follow RFC 7807 (Problem Details). Common codes:
401 — missing or invalid Bearer token (re-exchange credentials)
403 — token's scopes don't cover the operation
404 — resource doesn't exist or caller has no access (intentionally indistinguishable to avoid leaking existence)
413 — request body too large (photo upload limits)
429 — rate-limited; back off and retry after the Retry-After header
Rate limits
When a limit is hit the API responds with HTTP 429 Too Many Requests and a Retry-After header (seconds). Recommended client behavior is exponential backoff anchored on that header. Domain-level limits (invites) also surface as inline errors in the HTMX flows.
Scope
Limit
Window
Partition
Errors
/api/oauth/token
10
1m
client_id (form) → IP
429 Too Many Requests + Retry-After
/api/* (default)
60
1m
client_id (claim) → IP
429 Too Many Requests + Retry-After
Invite resend (per invite)
1
5m
Invite
429 Too Many Requests + Retry-After (HTMX: inline message)
Invite issuance (per user)
10
24h
Issuer user
429 Too Many Requests + Retry-After (HTMX: inline message)
Model reference
Note: The model reference below is generated from the live OpenAPI spec and is in English regardless of your interface language.
ChangeRoleRequest
Request body for changing a permission row's role. Owner cannot be set or changed.
role*
Role
CreateFamilyRequest
Request body for creating a family. Form-encoded for HTMX, JSON for API.
name*
string · 1..100
Display name. Required, trimmed; max 100 chars.
CreateInviteRequest
Request body for creating an invite. Form-encoded for HTMX, JSON for API.
email*
string (email) · 3..254
Recipient email address. Required; normalized (trim + lowercase) by the service.
role
Role
CreateKidRequest
Request body for creating a kid. Form-encoded for HTMX, JSON for API.
name*
string · 1..100
Display name. Required, trimmed; max 100 chars.
birthDate
string (date), nullable
Calendar date of birth (no time component, no timezone). Optional.
gender
Gender
birthHeight
number (double), nullable
Birth height, if known. Unit is per-kid (see KidModel.MetricUnits); set via the web UI, not this request.
birthWeight
number (double), nullable
Birth weight, if known. Unit is per-kid (see KidModel.MetricUnits); set via the web UI, not this request.
birthShoeSize
number (double), nullable
Birth shoe size, if known. Unit is per-kid (see KidModel.MetricUnits); set via the web UI, not this request.
familyId
integer (int32), nullable
Family to attach the kid to. Null falls back to user's default family.
CreateMemoryRequest
Request body for creating a memory. Photos are uploaded as multipart and
bound separately; this model carries only the structured non-binary fields.
text
string, nullable · 0..5000
Free-form text body. Optional, but the memory must end up with text, a metric, or at least one photo.
occurredOn*
string (date)
Calendar date the memory occurred on. Required.
height
number (double), nullable
Recorded height at the time of the memory. Unit is per-kid (see KidModel.MetricUnits or GET /api/metrics/units); range/step are enforced per the kid's assigned unit, or free when unassigned.
weight
number (double), nullable
Recorded weight at the time of the memory. Unit is per-kid (see KidModel.MetricUnits or GET /api/metrics/units); range/step are enforced per the kid's assigned unit, or free when unassigned.
shoeSize
number (double), nullable
Recorded shoe size at the time of the memory. Unit is per-kid (see KidModel.MetricUnits or GET /api/metrics/units); range/step are enforced per the kid's assigned unit, or free when unassigned.
isPrivate
boolean
Set true to make the memory visible only to you; defaults to false (public). Private memories never trigger notifications.
FamilyModel
Public representation of a family. A family is a grouping of kids that
share an owner / creator and that other users can be invited into.
id
integer (int32)
Unique family identifier.
name*
string, nullable
Display name.
createdById
integer (int32)
User id of the creator (also the implicit owner).
createdAt
string (date-time)
Created-at timestamp (UTC).
FamilyModelPageResult
Generic page envelope for cursor-paginated endpoints. `NextCursor` is
null when there are no more pages.
items
array, nullable
Items in the current page (may be empty on a final page).
nextCursor
string, nullable
Opaque cursor for the next page; null if no more pages.
Gender
(no properties)
InviteModel
Public representation of an invite. The opaque Atrict.Api.Models.InviteModel.Token is only
included for invites the caller is authorized to act on (their own kid's
pending invite list); recipient-facing endpoints expose only the metadata.
id
integer (int32)
Unique invite identifier.
token
string (uuid)
Opaque token used in the public landing URL.
kidId
integer (int32)
Kid the invite grants access to.
email*
string, nullable
Recipient email address (lower-cased on create).
role
Role
createdAt
string (date-time)
Created-at timestamp (UTC).
expiresAt
string (date-time)
Expires-at timestamp (UTC). Default TTL is 14 days; resending refreshes it.
createdById
integer (int32)
User id that created the invite (typically the kid's owner).
acceptedAt
string (date-time), nullable
Accepted-at timestamp (UTC); null while pending.
acceptedByUserId
integer (int32), nullable
User id that accepted; null while pending.
revokedAt
string (date-time), nullable
Revoked-at timestamp (UTC); also set when the invite was naturally expired by the sweep job.
InviteModelPageResult
Generic page envelope for cursor-paginated endpoints. `NextCursor` is
null when there are no more pages.
items
array, nullable
Items in the current page (may be empty on a final page).
nextCursor
string, nullable
Opaque cursor for the next page; null if no more pages.
KidModel
Public representation of a Kid. Returned from API endpoints; never includes
permission bookkeeping or soft-delete state.
id
integer (int32)
Unique kid identifier.
name*
string, nullable
Display name.
birthDate
string (date), nullable
Calendar date of birth (no time component, no timezone). Null if not recorded.
gender
Gender
familyId
integer (int32)
Family the kid belongs to.
ownerId
integer (int32)
Owner of the kid (user id).
birthHeight
number (double), nullable
Birth height, if recorded. Interpret using MetricUnits["height"].
birthWeight
number (double), nullable
Birth weight, if recorded. Interpret using MetricUnits["weight"].
birthShoeSize
number (double), nullable
Birth shoe size, if recorded. Interpret using MetricUnits["shoe"].
hasAvatar
boolean
True when an avatar image is uploaded.
createdAt
string (date-time)
Created-at timestamp (UTC).
metricUnits
object, nullable
The kid's configured display unit per metric ("height" | "weight" | "shoe"). Absent key = unitless (bare number). Use to interpret this kid's memory and birth metric values.
KidModelPageResult
Generic page envelope for cursor-paginated endpoints. `NextCursor` is
null when there are no more pages.
items
array, nullable
Items in the current page (may be empty on a final page).
nextCursor
string, nullable
Opaque cursor for the next page; null if no more pages.
MemoryModel
Public representation of a memory entry on a kid's timeline.
id
integer (int32)
Unique memory identifier.
kidId
integer (int32)
Kid this memory belongs to.
authorId
integer (int32)
Author user id.
text
string, nullable
Free-form text body (may be empty when memory is photo- or metric-only).
occurredOn
string (date)
Calendar date the memory occurred on (no time component, no timezone).
createdAt
string (date-time)
Created-at timestamp (UTC).
editedAt
string (date-time), nullable
Last-edited timestamp (UTC); null if never edited.
height
number (double), nullable
Recorded height at the time of the memory. Interpret using the kid's MetricUnits["height"]; null = not recorded.
weight
number (double), nullable
Recorded weight at the time of the memory. Interpret using the kid's MetricUnits["weight"]; null = not recorded.
shoeSize
number (double), nullable
Recorded shoe size at the time of the memory. Interpret using the kid's MetricUnits["shoe"]; null = not recorded.
isPrivate
boolean
True if visible only to the author; private memories are omitted from list/search for other users and skip notifications.
photos
array, nullable
Photos attached to this memory, ordered by display index.
MemoryModelPageResult
Generic page envelope for cursor-paginated endpoints. `NextCursor` is
null when there are no more pages.
items
array, nullable
Items in the current page (may be empty on a final page).
nextCursor
string, nullable
Opaque cursor for the next page; null if no more pages.
MemoryPhotoStatus
(no properties)
MetricUnitModel
A unit option from the metric-units catalog, localized for the request culture.
Returned by GET /api/metrics/units so consumers can interpret per-kid metric values
and present unit choices.
metric*
string, nullable
Metric this unit belongs to: "height" | "weight" | "shoe".
code*
string, nullable
Stable, locale-invariant unit code (e.g. "cm", "kg", "EU").
name*
string, nullable
Localized display name shown next to values.
description*
string, nullable
Localized human-readable description.
min
number (double), nullable
Minimum accepted value, if constrained.
max
number (double), nullable
Maximum accepted value, if constrained.
step
number (double), nullable
Granularity the value must align to, if constrained.
MetricUnitRefModel
A kid's assigned unit for one metric: stable code plus its localized display name.
code*
string, nullable
Stable, locale-invariant unit code (e.g. "cm", "kg", "EU").
name*
string, nullable
Localized display name shown next to values (e.g. "cm", "см").
PermissionModel
Public representation of a permission row — a single user's role on a single kid.
id
integer (int32)
Unique permission identifier.
kidId
integer (int32)
Kid the permission applies to.
userId
integer (int32)
User the permission was granted to.
role
Role
grantedAt
string (date-time)
Granted-at timestamp (UTC).
grantedById
integer (int32)
User id that granted this permission (typically the kid's owner).
inviteId
integer (int32), nullable
Invite id this permission was granted from, if any.
PermissionModelPageResult
Generic page envelope for cursor-paginated endpoints. `NextCursor` is
null when there are no more pages.
items
array, nullable
Items in the current page (may be empty on a final page).
nextCursor
string, nullable
Opaque cursor for the next page; null if no more pages.
PhotoModel
Public representation of a photo attached to a memory.
id
integer (int32)
Unique photo identifier.
memoryId
integer (int32)
Owning memory id.
kidId
integer (int32)
Owning kid id (denormalized for permission checks).
orderIndex
integer (int32)
Display order within the memory (0-based).
originalFilename*
string, nullable
Original filename as uploaded by the client.
width
integer (int32)
Pixel width of the encoded image.
height
integer (int32)
Pixel height of the encoded image.
status
MemoryPhotoStatus
createdAt
string (date-time)
Created-at timestamp (UTC).
ProblemDetails
type
string, nullable
title
string, nullable
status
integer (int32), nullable
detail
string, nullable
instance
string, nullable
RenameFamilyRequest
Request body for renaming a family.
name*
string · 1..100
New display name. Required, trimmed; max 100 chars.
Refresh-token plaintext. Omitted for grants that don't issue one (client_credentials).
scope*
string, nullable
Granted scopes (space-separated).
UpdateKidRequest
Request body for updating a kid. All fields are full-replace (HTMX edit form
posts every field on every save).
name*
string · 1..100
Display name. Required, trimmed; max 100 chars.
birthDate
string (date), nullable
Calendar date of birth (no time component, no timezone). Optional.
gender
Gender
birthHeight
number (double), nullable
Birth height. Unit is per-kid (see KidModel.MetricUnits); set via the web UI, not this request.
birthWeight
number (double), nullable
Birth weight. Unit is per-kid (see KidModel.MetricUnits); set via the web UI, not this request.
birthShoeSize
number (double), nullable
Birth shoe size. Unit is per-kid (see KidModel.MetricUnits); set via the web UI, not this request.
familyId
integer (int32), nullable
Family the kid belongs to. Setting a different family moves the kid.
UpdateMemoryRequest
Request body for updating a memory. Photos and removal lists travel as
separate multipart parameters in the HTMX flow; the API will model those
differently in a later task.
text
string, nullable · 0..5000
Free-form text body. Optional, but the memory must end up with text, a metric, or at least one photo.
occurredOn*
string (date)
Calendar date the memory occurred on. Required.
height
number (double), nullable
Recorded height at the time of the memory. Unit is per-kid (see KidModel.MetricUnits or GET /api/metrics/units); range/step are enforced per the kid's assigned unit, or free when unassigned.
weight
number (double), nullable
Recorded weight at the time of the memory. Unit is per-kid (see KidModel.MetricUnits or GET /api/metrics/units); range/step are enforced per the kid's assigned unit, or free when unassigned.
shoeSize
number (double), nullable
Recorded shoe size at the time of the memory. Unit is per-kid (see KidModel.MetricUnits or GET /api/metrics/units); range/step are enforced per the kid's assigned unit, or free when unassigned.
isPrivate
boolean
Set true to make the memory visible only to you, false to make it public. Note: flipping a public memory to private does not retract notifications already sent.