REST API
The Incantory REST API at /api/v1 - authentication, errors, caching, pagination and the full endpoint reference from the OpenAPI document.
Base URL and format
https://incantory.ai/api/v1Requests and responses are JSON (Content-Type: application/json) unless an endpoint says otherwise; /raw returns text/plain and /download returns an archive. Timestamps are ISO 8601 in UTC.
The machine-readable description is the OpenAPI 3.1 document at /api/v1/openapi.json. It is generated from the same schemas the server validates requests with, so it cannot drift from the implementation. Point an API explorer or a client generator at it.
Authentication
Send an API token as a bearer token:
GET /api/v1/prompts/alice/code-review HTTP/1.1
Host: incantory.ai
Authorization: Bearer inc_...Create tokens at Settings → Security. Scopes cap what a token can do, whatever your account may do on the site:
| Scope | Allows |
|---|---|
read | Reading, including your private and unlisted items |
write | Creating and updating prompts, versions, labels, forks, stars, watches and webhooks |
evals:write | Reporting eval runs and results only (for CI) |
Endpoints marked "optional" auth work anonymously and show more with a token; "required" answers 401 without one and 403 token_scope when the token lacks the scope. Some actions are never allowed to any token (minting tokens, changing sign-in methods, hard deletes).
Errors
Every error has the same shape:
{
"error": {
"code": "validation_failed",
"message": "Invalid request body",
"details": [{ "path": "version", "code": "invalid_type", "message": "Expected number" }],
"requestId": "5f0c1c9e-..."
}
}code is stable and meant for programs; message is for people. Quote the requestId (also in the X-Request-Id response header) when reporting a problem. The full list of codes is in Rate limits and errors.
Caching with ETags
Most GET responses carry an ETag. Send it back in If-None-Match and an unchanged resource answers 304 Not Modified with no body. Pinned versions (/versions/{n}) are immutable and cached for a year; polling a label with If-None-Match is the cheap way to notice a release.
curl -i -H 'If-None-Match: "abc123"' https://incantory.ai/api/v1/prompts/alice/code-review/labelsPagination
Lists use keyset cursors, never page numbers. A response carries nextCursor; pass it back as cursor to get the next page. null means there are no more. Treat cursors as opaque strings: their contents may change, and a malformed one answers 400 invalid_cursor.
curl "https://incantory.ai/api/v1/prompts?kind=skill&limit=50"
curl "https://incantory.ai/api/v1/prompts?kind=skill&limit=50&cursor=eyJ..."Rate limits
Requests are limited per token and per IP. See Rate limits and errors for the headers and how the SDKs retry.
Endpoints
187 operations in 27 groups, generated from the OpenAPI 3.1 document.
AI suggestions
Analytics
Blog
- GET
/api/v1/postsPublished blog posts, or your own - POST
/api/v1/postsCreate a draft post - GET
/api/v1/posts/{id}Get one post - PATCH
/api/v1/posts/{id}Edit a post - DELETE
/api/v1/posts/{id}Delete a post (soft) - PUT
/api/v1/posts/{id}/autosaveSave the working copy (editor autosave) - GET
/api/v1/posts/{id}/revisionsRevision history - GET
/api/v1/posts/{id}/revisions/{revisionId}One revision with its body - POST
/api/v1/posts/{id}/revisions/{revisionId}/restoreRestore a revision as the working text - POST
/api/v1/posts/{id}/submitSubmit for review (or publish, for trusted authors) - POST
/api/v1/posts/{id}/unpublishUnpublish a post - POST
/api/v1/posts/{id}/withdrawWithdraw a submission - GET
/api/v1/posts/seriesYour series - POST
/api/v1/posts/seriesCreate a series - GET
/api/v1/posts/series/{id}One series with its published posts in order - PATCH
/api/v1/posts/series/{id}Edit a series - DELETE
/api/v1/posts/series/{id}Delete a series - POST
/api/v1/posts/series/{id}/reorderReorder a series
Change requests
- GET
/api/v1/prompts/{owner}/{slug}/change-requestsList change requests on a prompt - POST
/api/v1/prompts/{owner}/{slug}/change-requestsPropose a version of your fork to this prompt - GET
/api/v1/prompts/{owner}/{slug}/change-requests/{n}Get a change request (with what the caller may do) - PATCH
/api/v1/prompts/{owner}/{slug}/change-requests/{n}Edit, close or reopen a change request - GET
/api/v1/prompts/{owner}/{slug}/change-requests/{n}/diffThe diff a change request proposes - POST
/api/v1/prompts/{owner}/{slug}/change-requests/{n}/mergeMerge a change request (target owner)
Collections
- GET
/api/v1/collectionsList collections - POST
/api/v1/collectionsCreate a collection - GET
/api/v1/collections/{id}A collection and the items you may see - PATCH
/api/v1/collections/{id}Edit a collection (owner or admin) - DELETE
/api/v1/collections/{id}Delete a collection (owner or admin) - POST
/api/v1/collections/{id}/itemsAdd a prompt, make or post (idempotent) - PUT
/api/v1/collections/{id}/itemsReorder items - DELETE
/api/v1/collections/{id}/itemsRemove an item by its target - PATCH
/api/v1/collections/{id}/items/{itemId}Set the note on an item - DELETE
/api/v1/collections/{id}/items/{itemId}Remove one item - GET
/api/v1/collections/membershipYour collections, flagged if they contain a target
Comments
- GET
/api/v1/commentsThreads on a target - POST
/api/v1/commentsComment or reply - PATCH
/api/v1/comments/{id}Edit your comment (within 24 hours) - DELETE
/api/v1/comments/{id}Delete a comment (author or moderator; replies stay) - POST
/api/v1/comments/{id}/hideHide a comment (moderators) - DELETE
/api/v1/comments/{id}/hideUnhide a comment (moderators); publishes a held comment - PUT
/api/v1/comments/lockLock or unlock a thread (owner or moderator) - GET
/api/v1/comments/mentions@handle autocomplete
Contests
- GET
/api/v1/contestsList contests - GET
/api/v1/contests/{slug}Get a contest - GET
/api/v1/contests/{slug}/eligibleYour work that could be entered - GET
/api/v1/contests/{slug}/entriesList entries - POST
/api/v1/contests/{slug}/entriesEnter a make or prompt - DELETE
/api/v1/contests/{slug}/entries/{id}Withdraw your entry - PUT
/api/v1/contests/{slug}/entries/{id}/scoreScore an entry (judges) - POST
/api/v1/contests/{slug}/entries/{id}/voteVote for an entry - DELETE
/api/v1/contests/{slug}/entries/{id}/voteRemove your vote
Discord
Evals
- GET
/api/v1/evals/compareCompare two runs of one prompt, case by case - GET
/api/v1/evals/datasetsA prompt's eval datasets - POST
/api/v1/evals/datasetsCreate a dataset on your prompt - GET
/api/v1/evals/datasets/{id}Get a dataset - PATCH
/api/v1/evals/datasets/{id}Rename / describe / change visibility - DELETE
/api/v1/evals/datasets/{id}Delete a dataset (soft) - GET
/api/v1/evals/datasets/{id}/casesList a dataset's cases - POST
/api/v1/evals/datasets/{id}/casesAdd cases (batch) - PATCH
/api/v1/evals/datasets/{id}/cases/{caseId}Edit a case - DELETE
/api/v1/evals/datasets/{id}/cases/{caseId}Delete a case - POST
/api/v1/evals/datasets/{id}/importImport cases from CSV or JSONL - GET
/api/v1/evals/runsRuns reported for a prompt (optionally one version or dataset) - POST
/api/v1/evals/runsCreate a run for a prompt version - GET
/api/v1/evals/runs/{id}Get a run (status, verdict, summary) - PATCH
/api/v1/evals/runs/{id}Finish a run, pin or unpin its verdict - DELETE
/api/v1/evals/runs/{id}Delete a run (audited) - GET
/api/v1/evals/runs/{id}/resultsA run's results in report order - POST
/api/v1/evals/runs/{id}/resultsAppend results (batch, ≤1000) - GET
/api/v1/evals/scoresPer-version score summary (latest run per model × dataset)
Examples
- POST
/api/v1/examples/{id}/approveApprove a submitted example (prompt owner or admin) - POST
/api/v1/examples/{id}/rejectReject a submitted example (prompt owner or admin) - GET
/api/v1/prompts/{owner}/{slug}/examplesList approved examples (plus your queue) - POST
/api/v1/prompts/{owner}/{slug}/examplesSubmit an example output - GET
/api/v1/prompts/{owner}/{slug}/examples/{id}Get one example - PATCH
/api/v1/prompts/{owner}/{slug}/examples/{id}Edit your example - DELETE
/api/v1/prompts/{owner}/{slug}/examples/{id}Delete an example (author, prompt owner or admin) - POST
/api/v1/prompts/{owner}/{slug}/examples/reorderSet the order of approved examples (prompt owner or admin)
Imports
- GET
/api/v1/importsYour recent imports - POST
/api/v1/importsStart an import (paste, URL, GitHub repo/folder, folder files) - GET
/api/v1/imports/{id}Import status, detected items, dedup hints and results - POST
/api/v1/imports/{id}/cancelCancel an import - POST
/api/v1/imports/{id}/commitImport the selected items as draft prompts - POST
/api/v1/imports/{id}/uploadUpload the next chunk - POST
/api/v1/imports/uploadUpload a zip or chat export (first chunk)
Installs
Leaderboards
Makes
- GET
/api/v1/makesThe makes feed - POST
/api/v1/makesCreate a make - GET
/api/v1/makes/{slug}Get one make - PATCH
/api/v1/makes/{slug}Edit a make - DELETE
/api/v1/makes/{slug}Delete a make (soft) - POST
/api/v1/makes/{slug}/filesAttach a downloadable file - PATCH
/api/v1/makes/{slug}/files/{id}Relabel a file - DELETE
/api/v1/makes/{slug}/files/{id}Remove a file - GET
/api/v1/makes/{slug}/files/{id}/downloadDownload a file (302 to the media host) - POST
/api/v1/makes/{slug}/files/reorderReorder files - POST
/api/v1/makes/{slug}/mediaAdd a gallery item (upload or embed) - PATCH
/api/v1/makes/{slug}/media/{id}Edit a gallery item (caption, alt, cover) - DELETE
/api/v1/makes/{slug}/media/{id}Remove a gallery item - POST
/api/v1/makes/{slug}/media/reorderReorder the gallery - POST
/api/v1/makes/{slug}/partsAdd a parts-list line - PATCH
/api/v1/makes/{slug}/parts/{id}Edit a parts-list line - DELETE
/api/v1/makes/{slug}/parts/{id}Remove a parts-list line - POST
/api/v1/makes/{slug}/parts/reorderReorder the parts list - POST
/api/v1/makes/{slug}/promptsLink a prompt version - DELETE
/api/v1/makes/{slug}/prompts/{linkId}Unlink a prompt version - POST
/api/v1/makes/{slug}/prompts/{linkId}/approveApprove a make link (prompt owner, moderator, admin) - POST
/api/v1/makes/{slug}/prompts/{linkId}/pinPin or unpin an approved make on the prompt's gallery - POST
/api/v1/makes/{slug}/prompts/{linkId}/rejectReject a make link, with an optional reason - POST
/api/v1/makes/{slug}/remixRemix a make - GET
/api/v1/makes/family-treeA prompt's family tree - GET
/api/v1/makes/galleryA prompt's approved makes, pinned first - GET
/api/v1/makes/inboxPending links waiting for your decision
Media
Models
Notifications
- GET
/api/v1/notificationsYour notifications - GET
/api/v1/notifications/countUnread count (0 when signed out) - POST
/api/v1/notifications/readMark notifications read (or unread) - GET
/api/v1/notifications/unsubscribeUnsubscribe confirmation page (HTML) - POST
/api/v1/notifications/unsubscribeOne-click unsubscribe from notification email (RFC 8058)
Open in…
Prompts
- GET
/api/v1/promptsList and search prompts - POST
/api/v1/promptsCreate a prompt (published v1, or a draft with publish=false) - GET
/api/v1/prompts/{owner}/{slug}Get a prompt at its latest version, a pinned version or a label - PATCH
/api/v1/prompts/{owner}/{slug}Edit metadata (title, summary, tags, license, visibility, rating, slug) - DELETE
/api/v1/prompts/{owner}/{slug}Soft-delete a prompt (it answers 410 afterwards) - GET
/api/v1/prompts/{owner}/{slug}/diff/{range}Diff two versions (`{range}` is `a..b`) - GET
/api/v1/prompts/{owner}/{slug}/downloadDownload as zip / tar.gz or converted to a tool format - GET
/api/v1/prompts/{owner}/{slug}/draftGet the working draft (owner only; null when none) - PUT
/api/v1/prompts/{owner}/{slug}/draftSave the working draft - DELETE
/api/v1/prompts/{owner}/{slug}/draftDiscard the working draft - POST
/api/v1/prompts/{owner}/{slug}/forksFork into your namespace - GET
/api/v1/prompts/{owner}/{slug}/labelsList labels - PUT
/api/v1/prompts/{owner}/{slug}/labels/{name}Create or move a label - DELETE
/api/v1/prompts/{owner}/{slug}/labels/{name}Delete a label - GET
/api/v1/prompts/{owner}/{slug}/labels/{name}/historyLabel move history, newest first - GET
/api/v1/prompts/{owner}/{slug}/rawThe entry file as text (or `?path=`) - GET
/api/v1/prompts/{owner}/{slug}/raw/{path}One file of a version as text - GET
/api/v1/prompts/{owner}/{slug}/versionsList versions, newest first (yanked versions only for the owner) - POST
/api/v1/prompts/{owner}/{slug}/versionsCommit a new immutable version (from the body, or the saved draft when files are omitted) - GET
/api/v1/prompts/{owner}/{slug}/versions/{n}Get one version with its files (immutable) - POST
/api/v1/prompts/{owner}/{slug}/versions/{n}/restoreRestore an old version as a new version - POST
/api/v1/prompts/{owner}/{slug}/versions/{n}/yankYank a version (hidden from lists, cannot be labelled; still served when pinned) - DELETE
/api/v1/prompts/{owner}/{slug}/versions/{n}/yankUnyank a version
Reports
Search
Stars
- POST
/api/v1/makes/{slug}/starStar a make (idempotent) - DELETE
/api/v1/makes/{slug}/starRemove your star from a make (idempotent) - GET
/api/v1/me/starsYour starred prompts, newest star first - POST
/api/v1/prompts/{owner}/{slug}/starStar a prompt (idempotent) - DELETE
/api/v1/prompts/{owner}/{slug}/starRemove your star (idempotent)
Tags
Users
Votes
Watch
Webhooks
- GET
/api/v1/webhooksList your webhooks - POST
/api/v1/webhooksCreate a webhook - GET
/api/v1/webhooks/{id}Get a webhook - PATCH
/api/v1/webhooks/{id}Update a webhook (owner only) - DELETE
/api/v1/webhooks/{id}Delete a webhook and its delivery log - GET
/api/v1/webhooks/{id}/deliveriesThe delivery log (newest first) - GET
/api/v1/webhooks/{id}/deliveries/{deliveryId}One delivery, with its payload - POST
/api/v1/webhooks/{id}/deliveries/{deliveryId}/redeliverRedeliver an event - POST
/api/v1/webhooks/{id}/testSend a test (ping) delivery - GET
/api/v1/webhooks/eventsThe webhook event catalogue