The Opal API gives every item two stable IDs: a 24-character submission ID and an item_ ID. Most routes accept either, but some need the submission ID, so store that one. Successful responses usually come under a data envelope, and errors use { "error": "..." }. Branch on the status code, not on the message text.
Item IDs
Every Opal item has two stable identifiers:
| Identifier | Format | Where it appears |
|---|---|---|
| Submission ID | 24-character hex string | _id, id, route params, binder and fence lists |
| Item ID | item_ plus a UUID | data.itemId, item URLs |
The :id parameter of item routes accepts either form. Some other values must be submission IDs, because Opal looks them up directly:
| Value | Accepts |
|---|---|
:id in any /items/:id route, including /page, /download, and /publish | Submission ID or item_ ID |
itemId in POST /shares and in POST /media/upload | Submission ID or item_ ID |
itemId and itemIds in POST /items/:id/binder/items | Submission ID only |
:itemId in DELETE /items/:id/binder/items/:itemId, and order in PATCH /items/:id/binder/reorder | Submission ID only |
itemId in POST /items/:id/fence/items, and :itemId in DELETE /items/:id/fence/items/:itemId | Submission ID only |
id in each POST /items/batch/move entry | Submission ID only |
itemId in POST /copies/create | Submission ID only |
linkedItem on tasks | Stored as given. Send the submission ID. |
| Workspace, share, copy, task, view, and API key IDs | Their own IDs, as returned by their routes |
Store submission IDs in integrations. Every route accepts them, and they avoid an extra lookup.
The Data Envelope
Most API-key routes return successful data under a data envelope:
{
"data": {}
}
These routes return a different shape:
| Route | Success shape |
|---|---|
GET /items/:id | { "data": item, "access": {...} }, with access beside data |
GET /items/inbox, GET /items/shared | { "data": { "items": [...], "total": n } } |
GET /shares/incoming, GET /shares/outgoing | { "data": { "shares": [...] } } |
GET /copies/pending | { "data": { "pending": [...], "total": n } } |
GET /tasks | { "data": { "tasks": [...], "total": n, "limit": n, "offset": n } } |
GET /search | { "data": { "results": [...], "total": n, "query": "..." } } |
GET /icons | { "data": [...], "listFailed": false } |
DELETE /icons/:blobName, POST /items/:id/notify-metadata | { "success": true }, no envelope |
GET /export/check | { "ok": true }, no envelope |
GET /export | The zip file itself |
/keys routes (signed-in app session) | Top-level success, key or keys, and message |
Error Shape
Errors use this shape:
{
"error": "Human-readable message"
}
Limit errors add fields. See Errors, Rate Limits, and Plan Limits in the Opal API. Share and publish routes add "success": false and a details field that is omitted in production. API key routes add "details": null. Branch on the status code and on code where one is present, not on the message text.
Status Codes
| Code | Meaning |
|---|---|
200 | Success |
201 | Created |
202 | Accepted: a large binder duplicate, or a reassignment with background, continues in the background |
400 | Missing or invalid input, or a count limit (binder, batch, keys, views) |
401 | Missing, malformed, unknown, or revoked API key |
403 | Plan, locked account, read-only key, ownership, share permission, or item or workspace limit |
404 | Resource not found, or not one of yours |
409 | Conflict: workspace address taken, declining a share that was already accepted, or an export already running |
413 | File size, storage, or item content limit |
415 | Icon upload that is not an image |
423 | The item is being handed to a new owner (code: "ITEM_TRANSFERRING"). Try again when that is done. |
429 | Rate limited, or exporting everything more than once a day |
500 | Server error |
502 | POST /shares could not create a share record. Nothing from that request was kept (code: "BULK_SHARE_FAILED"). |
Shared fences and reassigning an owner use these codes too. Shared fence refusals such as FENCE_FULL, FENCE_TOO_SMALL, FENCE_IN_INBOX, and FENCE_NOT_PLACED return 409, and a reassignment the new owner’s storage has no room for returns 409 with NO_ROOM. While a reassignment is under way, changes to what it moves return 423 with ITEM_TRANSFERRING. See Fences API: Add Items, Read Children, and Move a Fence and Reassign Owner API: Hand a Shared Item, Binder, or Fence to a Member.
The 401 messages are Missing or invalid Authorization header, Invalid API key format, Invalid or revoked API key, API key owner not found, and API key authentication failed.
Pagination
List routes page with a count and an offset:
GET /items:limit(default 50, max 100) andskip. See Items API: List, Get, Create, Update, and Delete.GET /items/inbox:limitandskipapply to owned items only. Shared inbox items are always all included.GET /items/shared:limit(default 50, max 100) andskip, applied to share records.GET /tasks:limit(default 100, max 1000) andoffset. See Tasks API: Create, List, Update, and Delete Tasks.GET /search:limit(default 20, max 100). See Search API: Find Items by Title, Description, and Content.
Next Steps
- Look up limit errors: Errors, Rate Limits, and Plan Limits in the Opal API
- Work with items: Items API: List, Get, Create, Update, and Delete
- See every endpoint: Opal REST API Endpoint Cheat Sheet
Get Help
Stuck on an API call or have a question? Ask in the Opal Discord or send us a message through the contact form.
FAQ
Which item ID should I store?
The submission ID, the 24-character ID returned as _id or id. Every route accepts it, and some routes accept only that form.
What does a 403 from the Opal API mean?
A 403 can mean a plan problem, a locked account, a read-only key, an ownership or share-permission problem, or an item or workspace limit. Check code in the response body, and see Errors, Rate Limits, and Plan Limits in the Opal API.
Should I read the error message to decide what to do?
No. Branch on the status code, and on code where one is present. Message text can change.
Why does GET /items/:id have an access block?
The access block sits beside data and tells you whether you are the owner or a share recipient, and which permissions you have. See Items API: List, Get, Create, Update, and Delete.
