Disconnect and errors
Disconnect your app, react when the venue owner disconnects it, and handle every error code, check, rate limit and body limit of the API.
Updated · View as Markdown
Your app can end its connection at any time. This page also lists every error, check and limit of the Live 3D API.
Disconnect
Send a signed DELETE https://floorplancraft.com/api/connections/self with no body, signed over zero bytes:
DELETE /api/connections/self HTTP/1.1
Host: floorplancraft.com
X-FPC-Connection: lc_8sKq2mXvT0bN4yR7wE1uZa
X-FPC-Timestamp: 1794054600
X-FPC-Signature: v1=<64 lowercase hex characters>- It answers
204 No Contentand ends the connection. Pushes and embed addresses then answer403 connection_revoked, and open live embeds close within a minute. - The origins your connection added to the plan embed's allowed origins are removed, unless the owner or another connection added them too.
- A repeat answers
204again. Disconnect works without Live 3D and after the plan is unshared. Limit: 5 at once, then 5 a minute. - Then delete the
connectionSecretyou stored.
When the owner disconnects
The venue owner can disconnect your app in the plan's Share dialog, under Connected apps. Unsharing or deleting the plan ends the connection too. Your next signed request gets 403 connection_revoked: stop pushing, show that the app is disconnected and offer to connect again.
Error codes
| Status | error | From | What to do |
|---|---|---|---|
| 400 | invalid_request | Connect request, code exchange | Fix the body. A connect request names each problem in issues; a code exchange leaves the code unused. |
| 400 | invalid_grant | Code exchange | Start the connect flow again. |
| 401 | unknown_connection | Signed requests | Check X-FPC-Connection. |
| 401 | stale_timestamp | Signed requests | Send whole Unix seconds and keep your clock in sync. |
| 401 | invalid_signature | Signed requests | Check the signed text, the key and the bytes you send. |
| 402 | entitlement_required | Pushes, live embed addresses | The workspace does not have Live 3D: see below. |
| 403 | connection_revoked | Signed requests | The connection ended or the plan is no longer shared: stop, and offer to connect again. |
| 403 | owner_access_required | Table sync | The person who connected is no longer an editor or admin of the workspace. |
| 404 | not_found | Every request | Live 3D connections are turned off on the server. |
| 409 | conflict | Table sync | The plan kept changing: try again. |
| 413 | body_too_large | Signed requests | Send at most maxBytes. |
| 422 | invalid_feed | Pushes | Fix the fields in issues. Nothing was stored. |
| 422 | invalid_sequence | Pushes | sequence jumped too far. Nothing was stored. |
| 422 | invalid_backfill | Backfill | Fix the fields in issues. Nothing was stored. |
| 422 | backfill_too_large | Backfill | The day would pass a limit (limit, max, needed). Send fewer floors or events. Nothing was stored. |
| 422 | invalid_request | Live embed addresses, table sync | Fix the body. |
| 422 | plan_too_large | Table sync | The plan would pass a limit. Nothing was added. |
| 422 | unsupported_plan | Table sync | The plan cannot take these tables: add them in the planner. |
| 422 | unsupported_app | Table sync | Booking and play venue apps cannot add tables. |
| 429 | rate_limited | Every request | Wait retryAfterMs milliseconds. |
| 503 | unavailable | Every request | Try again shortly. A code exchange keeps its code. |
Issues
A 400 or 422 with issues names each problem:
{ "error": "invalid_feed", "issues": [{ "path": "tables.3.state", "message": "…" }] }path names the field, counting from 0: tables.3.state is the fourth table's state. An empty path means the whole body. A connect request lists up to 50 issues and a push up to 20.
Live 3D access
{
"error": "entitlement_required",
"entitlement": "live_view",
"upgradeUrl": "https://floorplancraft.com/checkout/live-3d?connection=lc_8sKq2mXvT0bN4yR7wE1uZa"
}A 402 means the venue's workspace does not have Live 3D. Open upgradeUrl in a browser tab for the venue owner, who signs in and subscribes there. Do not parse or build the address yourself. Until then pushes are not stored: show the plan embed instead of the live view.
Check order
Signed requests are checked in this order, and the first failure answers:
- The connection feature is on (
404 not_found) and can run (503 unavailable). - Your server's address has not used up its allowance of failed requests (
429). X-FPC-Connectionislc_and 22 base64url characters (401 unknown_connection).- The body is within the endpoint's size limit (
413 body_too_large). X-FPC-Timestampis within 300 seconds of the server's clock (401 stale_timestamp).- The connection exists (
401 unknown_connection) and the signature matches (401 invalid_signature). - The connection is active (
403 connection_revoked). - The connection is within its own rate limit (
429). - The workspace has Live 3D (
402 entitlement_required). - The plan is still shared (
403 connection_revoked). - The body is valid (
422).
Failures in steps 3 to 6 count against your server's address. Disconnect skips steps 7, 9 and 10. Table sync skips step 9 and checks its body before step 10.
Rate limits
| Request | Limit |
|---|---|
| Connect request | 20 at once, then 60 an hour from one address (an IPv6 address counts by its /64); 10 at once, then 30 an hour for one install from one address; 120 at once, then 60 a minute from everyone together; at most 1,000 requests waiting for an owner |
| Push | 24 at once, then 12 a minute per connection |
| Live embed address | 10 at once, then 30 an hour per connection |
| Table sync | 6 at once, then 6 a minute per connection |
| Disconnect | 5 at once, then 5 a minute per connection |
| Failed signed requests and code exchanges | 60 at once, then 60 a minute from one address |
Every 429 has retryAfterMs in its body and a Retry-After header in seconds.
Body limits
| Request | Largest body |
|---|---|
| Connect request | 256 KB; larger is 400 invalid_request |
| Code exchange | 4 KB; larger is 400 invalid_request |
| Push | 512 KB; larger is 413 with "maxBytes": 524288 |
| Live embed address | 4 KB; larger is 413 |
| Table sync | 256 KB; larger is 413 |
| Disconnect | Send no body |