Sync & Jobs
Trigger a sync on a connection, read where it got to, and follow or cancel the background job doing the work.
Operations on this page
| Operation | Method and path | Python | Node.js |
|---|---|---|---|
| List recent sync jobs | GET /api/v2/integrations/connections/{connection_id}/sync | connections.sync_status | connections.syncStatus |
| Trigger a sync | POST /api/v2/integrations/connections/{connection_id}/sync | connections.trigger_sync | connections.triggerSync |
| Get a sync job | GET /api/v2/integrations/sync-jobs/{job_id} | sync_jobs.get | syncJobs.get |
| Cancel a sync job | POST /api/v2/integrations/sync-jobs/{job_id}/cancel | sync_jobs.cancel | syncJobs.cancel |
Authentication and scope
| Requirement | Contract |
|---|---|
| Credential | An API key sent as X-API-Key. Connector operations are not end-user scoped. |
| Read scope | integrations:read for every GET. |
| Write scope | integrations:write for every POST, PUT, PATCH and DELETE. |
| Tenant | Derived from the authenticated key. There is no tenant parameter to pass or to get wrong. |
X-End-User-ID | Not used. A connection belongs to the organization, not to one end user. |
1. Check before you trigger
Despite the method name, this returns a bare JSON array of recent sync jobs, newest first — not a single status object. Read the first entry to see whether one is already in flight; triggering a second sync wastes an upstream rate-limit budget you may need.
import osfrom memorysync import MemorySyncClientclient = MemorySyncClient(api_key=os.environ["MEMORYSYNC_API_KEY"],base_url="https://api.memorysync.io",)jobs = client.connections.sync_status("conn_8f21a4")if jobs and jobs[0]["status"] in {"pending", "running"}:print("already syncing:", jobs[0]["id"])else:print("idle; last job:", jobs[0]["status"] if jobs else "none yet")
| Parameter | Contract |
|---|---|
limit | Optional. Defaults to 20, capped at 100. |
2. Trigger a sync
A sync is queued, not performed inline. The response is the job record, and the identifier to follow is id.
import osfrom memorysync import MemorySyncClientclient = MemorySyncClient(api_key=os.environ["MEMORYSYNC_API_KEY"],base_url="https://api.memorysync.io",)job = client.connections.trigger_sync("conn_8f21a4", job_type="incremental")print(job["id"], job["status"])
| Field | Type | Contract |
|---|---|---|
job_type | string | Optional. Exactly incremental (the default) or full. Any other value is a 422. |
3. Follow the job
Poll the job, at a sensible interval. There is no completion webhook for sync jobs, so the job record is the source of truth.
import osfrom memorysync import MemorySyncClientclient = MemorySyncClient(api_key=os.environ["MEMORYSYNC_API_KEY"],base_url="https://api.memorysync.io",)import timeTERMINAL = {"completed", "failed", "cancelled", "partial"}while True:job = client.sync_jobs.get(job_id)if job["status"] in TERMINAL:breaktime.sleep(5)progress = job["progress"]print(job["status"], progress["processed_items"], "of", progress["total_items"],"failed:", progress["failed_items"])
| Field | Meaning |
|---|---|
id, connection_id | The job and what it belongs to. Both integers. |
job_type | full or incremental. |
status | One of the six values below. |
progress | An object: total_items, processed_items, failed_items. |
started_at, completed_at, created_at | Timing. The first two are null until they happen. |
error_message | Why a failure failed. |
Accepted and waiting for a worker.
Reading from the source and extracting. Objects appear as it goes.
Everything selected was processed.
Some items could not be read. Check progress.failed_items and the per-object detail.
Read error_message. A credential problem needs reconnect, not another sync.
Stopped early. Objects already processed are kept.
4. Cancel a long-running sync
Cancelling stops further work. Objects already synced and memories already extracted are kept, because discarding completed work would make a cancel more destructive than the sync it stopped.
import osfrom memorysync import MemorySyncClientclient = MemorySyncClient(api_key=os.environ["MEMORYSYNC_API_KEY"],base_url="https://api.memorysync.io",)job = client.sync_jobs.cancel(job_id)print(job["status"])
Billing
A sync is billed for what it extracts: one add per memory created, exactly like the memory API. Reading a source object that produces no memory is not billed. A full sync of a large connection therefore costs roughly what the original import cost.
Errors and next action
| Status | Meaning | Next action |
|---|---|---|
401 | Missing, malformed or inactive API key. | Check server configuration without printing the key. |
403 | The key lacks integrations:read or integrations:write. | Grant the scope on the key, or use a key that has it. |
404 | The connection, object or job is not visible to this tenant. | Confirm the identifier belongs to this organization. |
409 | The connection is in a state that forbids the operation. | Read the connection status first and act on it. |
429 | Rate limited, either by MemorySync or by the upstream provider. | Back off; do not tighten a polling loop in response. |
5xx | Service failure. | Treat a write outcome as uncertain and reconcile by reading the connection back. |