MemorySync
API Reference

Connection Lifecycle

Create, read, update, repair and remove a connection to an external source. These eight operations are identical for every provider — the provider-specific configuration lives on its own page.

Operations on this page

OperationMethod and pathPythonNode.js
List connectionsGET /api/v2/integrations/connectionsconnections.listconnections.list
Get one connectionGET /api/v2/integrations/connections/{connection_id}connections.getconnections.get
Create with an API keyPOST /api/v2/integrations/connections/api-keyconnections.create_with_api_keyconnections.createWithApiKey
Create with credentialsPOST /api/v2/integrations/connections/credentialsconnections.create_with_credentialsconnections.createWithCredentials
Update a connectionPATCH /api/v2/integrations/connections/{connection_id}connections.updateconnections.update
Delete a connectionDELETE /api/v2/integrations/connections/{connection_id}connections.deleteconnections.delete
Re-authorisePOST /api/v2/integrations/connections/{connection_id}/reconnectconnections.reconnectconnections.reconnect
Purge synced dataPOST /api/v2/integrations/connections/{connection_id}/purgeconnections.purgeconnections.purge

Authentication and scope

RequirementContract
CredentialAn API key sent as X-API-Key. Connector operations are not end-user scoped.
Read scopeintegrations:read for every GET.
Write scopeintegrations:write for every POST, PUT, PATCH and DELETE.
TenantDerived from the authenticated key. There is no tenant parameter to pass or to get wrong.
X-End-User-IDNot used. A connection belongs to the organization, not to one end user.

The shape of a connection

Connection lifecycle
  1. 11. Create

    Either by API key or credentials here, or by OAuth on the Providers & OAuth page.

  2. 22. Configure

    Choose what to sync using the connector's own configuration page.

  3. 33. Sync

    Trigger a sync and watch the job. Covered on Sync & Jobs.

  4. 44. Operate

    Inspect objects, pause noisy ones, re-extract after a prompt change.

  5. 55. End

    Purge keeps the connection and removes the data; delete removes both.

1. Choose how to authenticate

How does the provider authenticate?

A user grants access

Slack, Google Drive, Notion, OneDrive.

Use: Use OAuth initiate; do not use the two create operations here.

A long-lived API key

A provider that issues a token you hold.

Use: Use create_with_api_key.

A credential set

Amazon S3 and anything needing more than one secret.

Use: Use create_with_credentials.

2. Create the connection

Create with a single API key. The argument is provider; the field on the wire is provider_id, and both SDKs handle that translation.

import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
)
connection = client.connections.create_with_api_key(
provider="granola",
api_key=os.environ["GRANOLA_API_KEY"],
)
print(connection["connection_id"], connection["status"])
POST/api/v2/integrations/connections/api-key
201 Created

Create with a credential set, which is what Amazon S3 needs:

connection = client.connections.create_with_credentials(
provider="s3",
credentials={
"access_key_id": os.environ["AWS_ACCESS_KEY_ID"],
"secret_access_key": os.environ["AWS_SECRET_ACCESS_KEY"],
"region": "us-east-1",
"bucket": "acme-knowledge-base",
},
)
POST/api/v2/integrations/connections/credentials
201 Created
Response fieldMeaning
connection_idThe integer id to use in every later call. Not a string.
provider_idEchoed back.
statusWhether the credential was accepted. Branch on this, not on the HTTP status.
accountThe upstream account the credential resolved to, when the provider reports one.
detailWhy the status is what it is. Present on a rejection.

3. Confirm it is connected

Read the connection back and branch on status before configuring anything. A connection that exists is not necessarily usable.

import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
)
connection = client.connections.get("conn_8f21a4")
if connection["status"] != "connected":
print("not usable yet:", connection["status_message"], connection["error_code"])
GET/api/v2/integrations/connections/{connection_id}
200 OK
Connection status
pending
Awaiting authorisation

OAuth was initiated but the callback has not arrived. Nothing will sync yet.

connected
Usable

Authenticated. Configure it and sync.

error
Recoverable failure

Read status_message and error_code, then call reconnect rather than creating a second connection.

expired
Token expired

Needs a refresh. reconnect returns a fresh authorisation URL.

revoked
Access withdrawn

A user or the provider revoked access. Re-authorisation is required.

disabled
Turned off by an administrator

Deliberately stopped. Re-enabling is an administrative action, not a reconnect.

FieldMeaning
idThe integer connection id.
provider_id, provider_nameWhich source this connects to.
status, status_message, error_codeCurrent state and why.
external_workspace, external_account_idThe upstream workspace or account it is bound to.
sync_enabled, sync_direction, sync_frequencyWhether and how it syncs.
total_objects_syncedLifetime count of objects read.
last_sync_at, last_sync_status, next_scheduled_syncSync history and what is next.
connected_by, connected_at, created_atProvenance.

4. List what exists

List is the operation a dashboard is built on. It returns an object with counts beside the array, so a summary needs no second call.

import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
)
result = client.connections.list(status="connected")
print(result["total"], result["connected"], result["errors"])
for connection in result["connections"]:
print(connection["id"], connection["provider_id"], connection["status"])
GET/api/v2/integrations/connections
200 OK
ParameterTypeContract
statusstringOptional; the only filter this route accepts. One of the six connection statuses.
Response fieldMeaning
connectionsThe connections themselves.
totalHow many exist.
connectedHow many are healthy.
errorsHow many need attention. Drive an alert from this rather than counting client-side.

5. Reconfigure the schedule

update changes whether a connection syncs and how often. It does not change what is selected for sync — that is the connector's own configuration page — and it cannot rename anything.

import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
)
connection = client.connections.update(
"conn_8f21a4",
sync_enabled=True,
sync_frequency="daily",
)
print(connection["sync_frequency"])
PATCH/api/v2/integrations/connections/{connection_id}
200 OK
FieldAccepted values
sync_enabledtrue or false. Turning it off stops scheduled syncs; a manual trigger still works.
sync_frequencyExactly one of realtime, hourly, daily, manual. Anything else is a 422.
sync_directionExactly one of import, export, bidirectional.
include_patterns, exclude_patternsLists of objects. Provider-specific.

6. Repair a broken connection

When a token expires or a user revokes access, reconnect returns a fresh authorisation URL for the existing connection. Use it instead of creating a second connection: a new connection re-syncs everything from scratch and duplicates every memory the first one produced.

import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
)
result = client.connections.reconnect("conn_8f21a4")
print(result["authorization_url"], result["state"])
POST/api/v2/integrations/connections/{connection_id}/reconnect
200 OK
Response fieldMeaning
authorization_urlRedirect the user's browser here. Do not fetch it server-side.
stateIdentifies this attempt.
connection_idThe existing connection being repaired — unchanged.

7. Remove data, or remove everything

Two different endings, and choosing the wrong one is expensive:

import os
from memorysync import MemorySyncClient
client = MemorySyncClient(
api_key=os.environ["MEMORYSYNC_API_KEY"],
base_url="https://api.memorysync.io",
)
# Keep the connection, delete everything it produced.
result = client.connections.purge("conn_8f21a4")
print(result["objects_deleted"], result["memories_deleted"])
# Remove the connection and revoke the credential.
client.connections.delete("conn_8f21a4")
POST/api/v2/integrations/connections/{connection_id}/purge
200 OK
DELETE/api/v2/integrations/connections/{connection_id}
204 No Content
Response fieldMeaning
objects_deletedHow many synced objects were removed.
memories_deletedHow many extracted memories were removed.
PurgeDelete
Synced objectsRemovedRemoved
Extracted memoriesRemovedRemoved
The connection recordKeptRemoved
The stored credentialKeptRevoked
Next syncRe-imports from the sourceNothing to sync

Errors and next action

StatusMeaningNext action
401Missing, malformed or inactive API key.Check server configuration without printing the key.
403The key lacks integrations:read or integrations:write.Grant the scope on the key, or use a key that has it.
404The connection, object or job is not visible to this tenant.Confirm the identifier belongs to this organization.
409The connection is in a state that forbids the operation.Read the connection status first and act on it.
429Rate limited, either by MemorySync or by the upstream provider.Back off; do not tighten a polling loop in response.
5xxService failure.Treat a write outcome as uncertain and reconcile by reading the connection back.