Build a Zindies app with AI
An AI-facing guide for creators and shops to build their own apps (mainly UI) on top of the Zindies public API (OAuth / REST).
As a rule, produce something that runs as a single HTML + JavaScript file with minimal dependencies, so it can be tried just by opening the file.
The primary readers are AI coding agents. The intent is to let creators and shops quickly build small tools for their own use.
Markdown version for AI / crawlers → /build-with-ai.md
Connection info
Fetch the OpenAPI spec first and treat it as the single source of truth for endpoints, parameters, and responses. Do not invent field names.
- OpenAPI spec (JSON, top priority): https://api.zindies.co/v1/openapi.json
- OpenAPI spec (YAML): https://api.zindies.co/v1/openapi.yaml
- API documentation (Swagger UI): https://api.zindies.co/docs
- Connection discovery (.well-known/mcp.json): https://api.zindies.co/.well-known/mcp.json
- Service index (llms.txt): https://zindies.co/llms.txt
- API base URL: https://api.zindies.co/v1
- MCP server: https://mcp.zindies.co/
Authentication
There are two kinds of tokens. Pick one based on your use case.
- PAT — Simplest when a creator/shop builds a tool for themselves. Full-scope, no Anchor restriction, issued from the screen. (https://zindies.co/user/api)
-
OAuth 2.0 (Authorization Code + PKCE) — For apps distributed to multiple users. Access can be scoped by scopes and by Anchor (target entity).
(https://developer.zindies.co/applications)
scopes:
profile:read profile:write creations:read creations:write announcements:read announcements:write events:read events:write analytics:read
Never hardcode tokens in source or commit them to the repo. For distributed apps use OAuth with narrowed scopes and Anchor; even for personal tools, load the token from an input field or secure storage.
CORS (browser-only apps)
api.zindies.co has CORS configured, so browser-only apps can call it directly. Authentication is always the Bearer token in the Authorization header (no cookies).
| Scope | Allowed methods | Path |
|---|---|---|
| Reading public data | GET |
/v1/* |
| Personal area (favorites, event participation, etc.) | GET / POST / DELETE |
/v1/me/* |
| Anchor-scoped content writes (creations, announcements, events) | GET / POST / PATCH / DELETE |
/v1/creators/:token/*, /v1/places/:token/* |
Data model
Semantics: warm colors = individual entities (creator / creation / place); cool colors = gatherings / broadcasts (event / announcement). See the OpenAPI spec for detailed fields.
| Entity | Role | Key fields |
|---|---|---|
Creator Creator |
A creator (maker). Warm-color identity | token name title bio photo_url url |
Creation Creation |
A work (ZINE). Warm-color identity | token title description released_year price photo_url creators url |
Place Place |
A shop (retailer). Warm-color identity | token name address latitude longitude place_type url |
Event Event |
An event (day / period). Cool-color identity | event_type title started_at start_date place creators booths url |
Announcement Announcement |
Announcements from a creator/creation/place (polymorphic) | title body audience announceable_type created_at |
Endpoints
Public read (no auth)
GET /v1/creators— CreatorGET /v1/creators/:token— CreatorGET /v1/creations— CreationGET /v1/creations/:token— CreationGET /v1/places— PlaceGET /v1/places/:token— PlaceGET /v1/events— EventGET /v1/events/:id— EventGET /v1/announcements— AnnouncementGET /v1/announcements/:id— AnnouncementGET /v1/search
Personal area (Bearer required)
GET /v1/meGET /v1/me/entitiesGET / POST / DELETE /v1/me/favoritesGET /v1/me/collectionGET / POST / DELETE /v1/me/event_participationsGET /v1/me/reservations
Anchor-scoped writes (scope + Anchor binding required)
GET / POST / PATCH / DELETE /v1/creators/:creator_token/creations(scope: creations:write)GET / POST / PATCH / DELETE /v1/creators/:creator_token/announcements(scope: announcements:write)GET / POST / PATCH / DELETE /v1/creators/:creator_token/events(scope: events:write)GET / POST / PATCH / DELETE /v1/places/:place_token/announcements(scope: announcements:write)GET / POST / PATCH / DELETE /v1/places/:place_token/events(scope: events:write)
Writing content (Anchor)
Content writes are nested under a creator / place token. With OAuth, the token you use must be bound to the target creator/place (Anchor). Get the target token from /v1/me/entities.
POST /v1/creators/:creator_token/creations
PATCH /v1/creators/:creator_token/creations/:id
DELETE /v1/creators/:creator_token/creations/:id
Conventions
Query conventions shared by all GET endpoints. List endpoints return ETag / Last-Modified so you can cache with conditional GET.
- Paginate with page (1-based, default 1) and per (default 12, max 100)
- per is the number of items per page (max 100)
- random=N (random sampling of 1-100; cannot be combined with page / per)
- locale=ja|en|ko|zh-TW for server-side translation (default ja)
- places nearby search — lat / lng / radius_km
- events filters — from / to (YYYY-MM-DD) / area / kind / event_type=day|period|all
- search takes q (required, 2+ chars) / type=creator|creation|place|event|all
All responses are JSON. Errors use the shape { "error": "...", "message": "..." }; 401 = auth error, 404 = not_found, 400 = bad parameters.
App-building tips
- {"Always provide the three states": "loading, empty, and error."}
- Implement pagination or random display.
- Use photo_url / photos_urls for images.
- Consider supporting multiple languages via the locale parameter.
What not to do
- Do not use fields or endpoints not present in the OpenAPI spec.
- Do not embed tokens in source or commit them to Git.
- Do not send cookies/credentials to public endpoints (Bearer only).
- Do not try to display private/draft data (the API returns public data only).