InstaMap API · v1
Build on your collection data
The InstaMap API lets another app read or manage your items, collections, listings, and sales. It needs an Enterprise plan. Data uses JSON. An API key controls what each app can access.
API key management
Enterprise space owners and admins can make API keys in space settings. Choose what each key can access. Use a separate key for each connected app. You can then replace or remove one key without stopping other apps.
- Grant only the scopes the integration needs.
- Store keys in a server-side secret manager, never source control or browser code.
- Revoke a key immediately when an integration or operator no longer needs access.
Authentication
Authenticate every request with an API key in the Authorization header as a bearer token. Create and manage keys in your Enterprise team settings — the full key is shown once, so store it somewhere safe.
curl https://instamap.ai/api/public/v1/items \
-H "Authorization: Bearer imk_live_your_key_here"Keys are scoped — each key only works for the scopes you grant it (e.g. items:read). Keep keys server-side; never expose them in a browser or mobile app.
Quickstart
- Open your Enterprise team settings → API keys.
- Create a key, choose its scopes, and copy the secret (shown once).
- Call the API with the key in the
Authorizationheader.
const res = await fetch("https://instamap.ai/api/public/v1/items?per_page=10", {
headers: { Authorization: `Bearer ${process.env.INSTAMAP_API_KEY}` },
});
const { data, pagination } = await res.json();
console.log(data.length, "items; more?", pagination.has_more);Run these examples from a server or trusted backend job. Do not ship API keys in browser code.
import os, requests
r = requests.get(
"https://instamap.ai/api/public/v1/items",
headers={"Authorization": f"Bearer {os.environ['INSTAMAP_API_KEY']}"},
params={"per_page": 10},
)
r.raise_for_status()
print(r.json()["data"])Versioning
The major API version is part of every URL: /api/public/v1. Version v1 may gain new fields. Your app should ignore fields it does not know. Changes that would break your app use a new main version. We provide steps to move to it.
Unsupported major paths return unsupported_api_version with the supported path and documentation link; existing v1 clients continue unchanged.
Webhooks
Opt-in comic beta · disabled by default
Enterprise space admins can add an HTTPS address to receive events. Its API key needs both comics:changes:read and comics:webhooks:write. Events contain compact permitted catalog references; fetch authorized details through the comic API.
An event may be sent more than once. Retries keep the same event ID, including manual retries within seven days. Events can arrive out of order. Check the revision or sequence number. Use deletion markers and follow merged_into_id.
{
"id": "95dd5a89-8199-47f5-a17b-96ea8dac61da",
"type": "comic.catalog.changed",
"created_at": "2026-10-01T12:00:00.000Z",
"data": { "change": {
"sequence": "1842", "entity_kind": "edition", "entity_id": "9007199254740993",
"action": "merge", "revision": "7", "merged_into_id": "9007199254741999"
}}
}Verify v1=HMAC_SHA256(secret, timestamp + "." + rawBody) from X-InstaMap-Webhook-Signature. Reject stale timestamps before constant-time comparison. During the 24-hour rotation overlap, the header carries signatures from both secrets.
import crypto from "node:crypto";
const expected = crypto
.createHmac("sha256", process.env.INSTAMAP_WEBHOOK_SECRET)
.update(timestamp + "." + rawBody)
.digest();
const valid = signatureHeader.split(",").some(value => {
const supplied = value.startsWith("v1=")
? Buffer.from(value.slice(3), "hex")
: Buffer.alloc(0);
return supplied.length === expected.length &&
crypto.timingSafeEqual(supplied, expected);
});Each message is at most 64 KB. Messages are sent one at a time to each address. Failed sends are retried with a longer wait, up to a set limit. Sending stops after repeated failures. Delivery logs never include signing secrets or response content.
Request IDs
Every API response includes X-Request-Id. Save it in your logs and include it when you contact support. It helps us find the request. Do not send your API key or customer data.
curl -sS -D - https://instamap.ai/api/public/v1/items \
-H "Authorization: Bearer $INSTAMAP_API_KEY" \
-o /dev/null | grep -i x-request-idRate Limits
Requests are limited per API key. When you exceed the limit you get a 429 response; check the standard RateLimit-* response headers to pace your requests. Every response also includes an X-Request-Id for support.
Errors
Route errors use the envelope below and conventional HTTP status codes. Authentication, scope, and rate-limit failures retain the original v1 error string for existing clients and add the same structured fields under error_details.
{
"error": {
"type": "not_found",
"message": "No item with that id."
}
}| Status | type | Meaning |
|---|---|---|
| 400 | invalid_request | Malformed request or bad parameter. |
| 401 | — | Missing or invalid API key. |
| 403 | — | The key lacks the required scope. |
| 403 | limit_reached | Your plan's item limit is reached (on create). |
| 404 | not_found | Resource not found. |
| 429 | — | Rate limit exceeded. |
| 410 | cursor_expired | Run the bounded resync URL, then resume change replay. |
Pagination
List endpoints accept page (1-based) and per_page (1–100, default 20), and return a pagination object with has_more.
{
"object": "list",
"data": [ /* … */ ],
"pagination": { "page": 1, "per_page": 20, "has_more": true }
}Comic endpoints use opaque cursor and limit parameters instead of page numbers. A cursor is valid only for the endpoint that issued it.
Opt-in beta · disabled by default
Comics
Catalog results are shared only when the source allows public API use. Each result names the source, license, allowed uses, and fields covered. Catalog BIGINT IDs use decimal text. Copy IDs use UUIDs.
Private wishlist, reading, and pull sections require both the comics:user:read scope and an explicit per-user grant selected when the key is created. A team key never inherits another member’s private activity.
/comics/editionsscope comics:catalog:readList redistributable catalog editions with stable cursors and source attribution. Use the per-record ETag on edition detail requests.
Parameters
cursor— Opaque continuation cursor.limit— 1–100 records.
curl "https://instamap.ai/api/public/v1/comics/editions?limit=50" \
-H "Authorization: Bearer $INSTAMAP_API_KEY"/comics/copiesscope comics:copies:readList only this key’s team copies. Add include=custom_fields only with comics:copies:custom.
Parameters
include— Optional custom_fields; requires its separate scope.cursor— Opaque continuation cursor.
curl "https://instamap.ai/api/public/v1/comics/copies?include=custom_fields" \
-H "Authorization: Bearer $INSTAMAP_API_KEY"/comics/user-exportscope comics:user:readExport only explicitly granted sections for the user who created the key.
Parameters
sections— Comma-separated wishlist, reading, and/or pulls.
curl "https://instamap.ai/api/public/v1/comics/user-export?sections=wishlist,reading" \
-H "Authorization: Bearer $INSTAMAP_API_KEY"/comics/changesscope comics:changes:readReplay compact upsert, tombstone, and merge references. Store the returned next cursor only after applying the page.
Parameters
cursor— Last committed replay cursor; omit for the beginning.limit— 1–100 records.
curl "https://instamap.ai/api/public/v1/comics/changes?cursor=$COMIC_CURSOR&limit=100" \
-H "Authorization: Bearer $INSTAMAP_API_KEY"Items
/itemsscope items:readList items in your team, newest first.
Parameters
page— Page number (1-based).per_page— Results per page (1–100, default 20).status— Filter: keep, sell, trade, sold, archived.
curl "https://instamap.ai/api/public/v1/items?status=sell&per_page=20" \
-H "Authorization: Bearer $INSTAMAP_API_KEY"/items/{id}scope items:readRetrieve a single item by id.
curl https://instamap.ai/api/public/v1/items/itm_123 \
-H "Authorization: Bearer $INSTAMAP_API_KEY"/itemsscope items:writeCreate an item in one of your collections. Counts against your plan's item limit.
curl -X POST https://instamap.ai/api/public/v1/items \
-H "Authorization: Bearer $INSTAMAP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"collection_id": "00000000-0000-0000-0000-000000000000",
"name": "Custom Otto",
"status": "keep",
"condition": "loose_mint",
"estimated_value": 24.99
}'/items/{id}scope items:writePartially update an item — only the fields you send change.
curl -X PATCH https://instamap.ai/api/public/v1/items/itm_123 \
-H "Authorization: Bearer $INSTAMAP_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "status": "sell", "estimated_value": 30 }'Collections
/collectionsscope collections:readList your team's collections.
Parameters
page— Page number (1-based).per_page— Results per page (1–100, default 20).
curl https://instamap.ai/api/public/v1/collections \
-H "Authorization: Bearer $INSTAMAP_API_KEY"Marketplace
/marketplace/listingsscope marketplace:readList your items currently for sale or trade.
Parameters
page— Page number (1-based).per_page— Results per page (1–100, default 20).
curl https://instamap.ai/api/public/v1/marketplace/listings \
-H "Authorization: Bearer $INSTAMAP_API_KEY"Sales
/sales/summaryscope analytics:readAggregate earnings: gross, fees, net payout, refunds, disputes.
curl https://instamap.ai/api/public/v1/sales/summary \
-H "Authorization: Bearer $INSTAMAP_API_KEY"