{"name":"Contents.team API changelog","url":"https://developers.contents.team/changelog","entries":[{"date":"2026-11-02","title":"Test-mode pipeline webhooks, the rest of the MCP review tools, OAuth app approval","changes":["An OAuth app registered in Settings needs Contents.team approval before its tokens work, as a live API key does: until then they return 403 oauth_app_pending_approval. Apps that register themselves through dynamic client registration (an assistant connecting to the MCP server) are unaffected.","Test endpoints now receive photos.analysis_completed, items.priced and export.ready for test claims (livemode: false), so a test key can run the whole flow end to end.","New MCP tools add_item, delete_item, unapprove_items and reject_items, matching POST /api/v1/claims/{claimId}/items, DELETE /api/v1/items/{itemId} and POST .../items/unapprove and .../items/reject. Each needs items:write and takes an idempotencyKey; add_item requires one, so a retried add never creates (and bills) a second item.","The API reference is now rendered by Contents.team from the same OpenAPI document, with a curl example for every endpoint."]},{"date":"2026-11-01","title":"Review and approve items through the API and MCP","changes":["New scope items:write: edit, add, delete, approve and reject items. It does not include items:read.","PATCH /api/v1/items/{itemId} edits name, model, quantity, unitCostCents, priceSource, priceSourceUrl, roomId, condition, estimatedAgeYears and notes, with the app's validation and price caps. An item being priced is a 409 item_locked.","POST /api/v1/claims/{claimId}/items/approve approves up to 1000 items and reports each id as approved, alreadyApproved, locked, skipped (with a reason such as unpriced) or notFound. POST .../items/unapprove and POST .../items/reject (up to 100) do the reverse.","POST /api/v1/claims/{claimId}/items adds an item by hand (approved on creation, as in the app); DELETE /api/v1/items/{itemId} removes one.","GET /api/v1/items/{itemId}/replacements lists the replacement finder's offers (rpl_ ids); POST /api/v1/items/{itemId}/replacements/{replacementId}/accept prices the item from one and approves it.","Items have priced and needsReview fields, and GET /api/v1/claims/{claimId}/items takes ?needsReview= and ?priced=.","inventory.approved is also sent when a replacement offer is accepted, in the app or through the API.","API approvals are metered exactly like approvals in the app; test claims are never billed.","MCP: get_replacements, update_item, approve_items and accept_replacement; get_inventory takes needsReview and priced.","New guide: Review and approve."]},{"date":"2026-11-01","title":"MCP: idempotencyKey on write tools","changes":["create_claim, add_photos and export_report take an optional idempotencyKey argument (the Idempotency-Key rules: 1-255 visible ASCII characters, 24 hours). A retry with the same key and arguments returns the first result instead of acting twice; the same key with different arguments is an idempotency_key_reused tool error."]},{"date":"2026-11-01","title":"API v1: keys, claims and the developer portal","changes":["Org API keys: owners and admins create them in Settings -> Connections -> API keys. ctk_test_ keys for test mode, ctk_live_ keys for live data; each key carries scopes.","GET /api/v1/me returns the calling key, its scopes and its organization.","GET /api/v1/claims lists claims newest first, with cursor pagination and externalRef and updatedSince filters.","Claims have an externalRef field for your own id.","The OpenAPI 3.1 document is public at /api/v1/openapi.json and /openapi/v1.yaml.","developers.contents.team: guides, the API reference, llms.txt, changelog.json and mcp.json.","The MCP server at https://contents.team/api/mcp (Streamable HTTP, stateless): list_claims, create_claim, add_photos, get_claim_status, get_inventory and export_report, authenticated with an API key or OAuth access token."]}]}