API controller for Sync cross-site operations.
The remote site is not trusted: every action treats its parameters as
data, and the actions that read tables authorize each request through
PhoenixKitSync.Connections.authorize_request/3, the same function the
WebSocket path calls.
Endpoints
POST /{prefix}/sync/api/register-connection- Register an incoming connection (unauthenticated; the incoming mode decides what it becomes)POST /{prefix}/sync/api/update-status- The sender reports a status for this site's receiver connectionPOST /{prefix}/sync/api/delete-connection,verify-connection,get-connection-status- Connection housekeeping between the two sitesPOST /{prefix}/sync/api/list-tables,pull-data,table-schema,table-records- What a receiver reads from this site's sender connectionGET /{prefix}/sync/api/status- Whether the module accepts connections
Summary
Functions
Deletes a connection when requested by the remote site.
Returns the current status of a connection.
Lists available tables for sync.
Pulls data for a specific table.
Registers an incoming connection from a remote site.
Health check endpoint for DB Sync API.
Returns records from a specific table for preview.
Returns schema for a specific table.
Mirrors a status the sender reports onto this site's receiver connection.
Verifies a connection still exists.
Functions
Deletes a connection when requested by the remote site.
Called when a receiver deletes their connection - the sender should also delete.
Expected JSON body:
sender_url(required) - URL of the site sending this requestauth_token_hash(required) - The auth token hash to identify the connection
Responses
- 200 OK - Connection deleted successfully
- 404 Not Found - Connection not found
- 503 Service Unavailable - DB Sync module is disabled
Returns the current status of a connection.
Called by receiver to get the sender's current connection status. This allows receivers to sync their status with the sender. It only reads: no status changes here, a pending connection included.
Expected JSON body:
receiver_url(required) - URL of the receiver site requesting status; logged, not matched (the token hash names the connection)auth_token_hash(required) - The auth token hash to identify the connection
Responses
- 200 OK - Returns connection status
- 404 Not Found - Connection not found
- 503 Service Unavailable - DB Sync module is disabled
Lists available tables for sync.
Called by receiver to get a list of tables that can be synced from this sender.
Expected JSON body:
auth_token_hash(required) - The auth token hash to identify the connectionpassword(optional) - The connection's download password, when it has oneinclude_checksums(optional) -falseleaves the per-table content checksum out ("checksum": null), sparing the sender an md5 over every table; anything else includes it
Responses
- 200 OK - Returns list of tables with row counts and sizes
- 401 Unauthorized - Invalid auth token
- 403 Forbidden - The connection may not be used now (
error_codesays why: not active, expired, a limit reached, IP, hours, password) - 429 Too Many Requests - Over the connection's requests per minute
(
error_coderate_limited;Retry-Afterandretry_aftergive the seconds until the minute frees) - 503 Service Unavailable - DB Sync module is disabled
Pulls data for a specific table.
Called by receiver to fetch table data during sync.
Expected JSON body:
auth_token_hash(required) - The auth token hash to identify the connectiontable_name(required) - Name of the table to pullconflict_strategy(optional) - How to handle conflicts (skip, overwrite, merge)ids(optional) - Up to 1000 key values to pull, orid_start/id_end(optional) - An integer key range; either bound may be left outafter(optional) - Thenext_afterof the previous answer: only the rows after that key are sent (PhoenixKitSync.PullCursor)cursor(optional) - Thecursorof the previous answer. With it the page counts as part of the download that produced it rather than as a new onepaged(optional) -truefrom a receiver that followsnext_afterpassword(optional) - The connection's download password, when it has one
The filter needs a single-column key and is compared in the key's own
type (PhoenixKitSync.PullFilter). It is read only after the token and
the table pass their checks.
Responses
- 200 OK - Returns table data in key order;
"filtered": truewhen a filter was applied."has_more"says whether rows are left past this answer, which stops at the connection'smax_records_per_request. When they are,"truncated": trueis set as well (the key is left out otherwise; it is what a receiver without cursors reads), and"next_after"and"cursor"continue the pull. A key whose type has no cursor gets"truncated"and"unsupported_key_type", the type's name. - 400 Bad Request - Missing fields, an invalid filter or cursor, a key
type that takes no filter, or a table without a primary key
(
"error_code": "no_primary_key": without a key its rows have no order to page in) - 401 Unauthorized - Invalid auth token
- 403 Forbidden - The connection may not be used now, or not for this table
- 429 Too Many Requests - Over the connection's requests per minute
(
error_coderate_limited;Retry-Afterandretry_aftergive the seconds until the minute frees) - 404 Not Found - Table not found
- 503 Service Unavailable - DB Sync module is disabled
Registers an incoming connection from a remote site.
Expected JSON body:
sender_url(required) - URL of the site sending this requestconnection_name(required) - Name for the connectionauth_token(required) - The auth token for the connectionpassword(optional) - Password if this site requires one
Responses
- 200 OK - Connection registered;
connection_statusis"active"under theauto_acceptmode or after a matching password, and"pending"underrequire_approval, where an admin of this site approves it - 400 Bad Request - Missing required fields
- 401 Unauthorized - Invalid password
- 403 Forbidden - Incoming connections are denied
- 409 Conflict - Connection already exists for this site
- 429 Too Many Requests - Too many registrations are awaiting approval
- 503 Service Unavailable - DB Sync module is disabled
Health check endpoint for DB Sync API.
Returns whether the module is enabled and accepting connections.
Returns records from a specific table for preview.
Expected JSON body:
auth_token_hash- Hash of the auth tokentable_name- Name of the tablelimit- Maximum number of records (default: 10)offset- Offset for pagination (default: 0)ids(optional) - List of specific IDs to fetchid_start,id_end(optional) - ID range filter
The filter is pull-data's (PhoenixKitSync.PullFilter).
Every answer counts as one download and its rows as records, against
max_downloads and max_records_total like a pull's.
Returns:
- 200 OK with records, ordered by the key (fewer than
limitwhen less is left of the record limit) - 400 Bad Request - An invalid filter, a key type that takes no filter,
or a table without a single-column key (
error_codesays which) - 401 Unauthorized
- 404 Not Found
Returns schema for a specific table.
Expected JSON body:
auth_token_hash- Hash of the auth tokentable_name- Name of the table
Returns:
- 200 OK with schema data
- 401 Unauthorized
- 404 Not Found
Mirrors a status the sender reports onto this site's receiver connection.
Called when the sender suspends, reactivates, or revokes its connection.
Only the "receiver" row for that sender is looked up, and
Connections.apply_remote_status/2 decides whether the change is one a
peer may make: it can suspend or revoke an active connection and lift a
suspension it reported itself. It can never activate a pending, revoked
or locally suspended connection, and never touches a "sender" row,
whose status decides what the peer may read.
Expected JSON body:
sender_url(required) - URL of the site sending this requestauth_token_hash(required) - The auth token hash to identify the connectionstatus(required) - The new status ("active", "suspended", "revoked")
Responses
- 200 OK - Status updated, or already that status
- 404 Not Found - No receiver connection for that sender and token
- 409 Conflict - The remote site may not make this change
- 503 Service Unavailable - DB Sync module is disabled
Verifies a connection still exists.
Called by sender to check if receiver still has the connection. Used for self-healing when the receiver was offline during delete.
Expected JSON body:
sender_url(required) - URL of the site sending this requestauth_token_hash(required) - The auth token hash to identify the connection
Responses
- 200 OK - Connection exists
- 404 Not Found - Connection not found (deleted)
- 503 Service Unavailable - DB Sync module is disabled