Makini
v4 (Latest)
  • v4 (Latest)
  • v3 (Legacy)
User Guide
API ReferenceMCPPlatforms
User Guide
API ReferenceMCPPlatforms
Website
v4 (Latest)
  • v4 (Latest)
  • v3 (Legacy)
v4 (Latest)
  • v4 (Latest)
  • v3 (Legacy)
  1. Management API
  • Getting Started
    • On-premise systems
    • Authentication
    • Testing with API Tools
    • Account setup
    • Connection Credits
  • Core Concepts
    • Connections
    • Unified Data Model
    • Custom mappings
    • Data mappings
    • Sync schedules and history
  • Admin API
  • Account & Team
    • Team access and SSO
  • Makini Link
    • Embedded connection settings
    • Launching Makini Link
    • Magic links
  • Management API
    • Management API authentication
    • Managing connections
    • Managing your application
  • Webhooks
    • Signatures and retries
    • Webhook events
  • Working with the API
    • Access tokens
    • Errors
    • Filtering
    • Makini Query Language
    • Raw data and passthrough
    • Reading data
    • Relations and expand
    • Writing data
  1. Management API

Managing connections

The Management API lets your backend run the whole connection lifecycle: create connections, check on them, switch them off and on, and remove them. Every change also reaches you as a webhook.

Before you start#

All routes are under https://api.makini.io/mgmt. Call them with a client_credentials token, as described in Management API authentication:
ScopeAllows
connections:readListing and reading connections
connections:writeCreating, updating, activating, deactivating and deleting them
The examples below keep the token in $TOKEN. A connection is always your application's own: an id that belongs to another application answers 404, exactly like one that doesn't exist.

The connection object#

Every route returns connections in the same shape. Credentials are never included.
FieldMeaning
idThe connection id.
name, emailThe name and contact email of the person or company the connection belongs to.
platformThe platform key, for example upkeep. null until one is chosen.
userMetadataYour own key-value data, such as your customer id. Makini stores it and hands it back.
connectedAtWhen the credentials first arrived, or null while the connection waits for them.
deactivatedAtWhen the connection was deactivated, or null while it's active.
credentialsExpiredAtWhen the connected system last refused the stored credentials, or null. New credentials clear it.
createdAt, updatedAtWhen the connection was created and last changed.

Create a connection#

POST /connections creates a connection in one of two ways.

Without credentials#

Create the connection first, then let your user enter the credentials in Makini Link. This is the usual path: your backend knows who the customer is, and the user only has to sign in to their own system.
{
  "connection": {
    "id": "5b0c6f0e-2a4e-4a51-9d6c-1f3e8a7b2c90",
    "name": "Acme Manufacturing",
    "email": "maintenance@acme.example",
    "platform": "upkeep",
    "userMetadata": { "customerId": "4711" },
    "connectedAt": null,
    "deactivatedAt": null,
    "credentialsExpiredAt": null,
    "createdAt": "2026-09-25T09:12:03.000Z",
    "updatedAt": "2026-09-25T09:12:03.000Z"
  }
}
The response also carries clientId and a few other fields; see the API reference for the full schema.
Every field is optional, so you can create a connection with nothing but a name and let the user choose the platform. To finish it, send the user to Makini Link with the connection's id in connection_id. Link fills in the credentials of this connection instead of creating a new one, and skips every question the connection already answers. A connection without credentials uses no connection credits.

With credentials#

If you already hold the credentials, send them in credentials, together with platform. The fields are the ones the platform's Makini Link form asks for.
Makini checks the credentials with the connected system before it saves anything. If the system refuses them, the answer is 401 MAKINI_SYNC_CREDENTIALS_REJECTED and no connection exists. See Errors for every refusal. Once saved, the connection starts syncing and uses its connection credits. If your workspace is out of credits and Allow overspend is off, the connection is still created, but deactivated. See Connection credits.
A platform with more than one access method needs the method named in adapterSlug. Without it, the answer is a 400 that lists the choices.

Safe retries#

Send an Idempotency-Key header (1 to 200 printable characters, no spaces) to make a create safe to retry. A repeat with the same key returns the connection the first request created, with the header Idempotent-Replayed: true, and creates nothing new: no second connection, no second charge. The same key with a different platform is a 409. Without a key, every request creates a new connection.

List and get connections#

The list answers {"data": [...]} with every live connection of your application, oldest first. Deleted connections aren't included.
Narrow it with filter[...] query parameters, which combine with AND:
FilterMatches
filter[userMetadata.<key>]=<value>Connections whose userMetadata has that key with exactly that value. Use it to find the connection for one of your customers, for example filter[userMetadata.customerId]=4711.
filter[name]=<text>Name contains the text, case-insensitive.
filter[email]=<text>Email contains the text, case-insensitive.
filter[platform]=<key>Exact platform key.
filter[status]=<status>active, pending (no credentials yet), expired (the connected system refused the credentials) or deactivated.
Send page or perPage to page the list (perPage is at most 500, 100 by default). A paged answer carries meta:
{ "data": [...], "meta": { "page": 2, "perPage": 100, "total": 240 } }
A single connection answers {"connection": {...}}. A deleted connection is a 404.

Update a connection#

PUT /connections/{id} changes name, email, platform, userMetadata or credentials. Send only the fields you want to change; userMetadata is replaced as a whole.
New credentials are checked with the connected system first, exactly as on create. When your user needs to re-enter credentials, the simplest path is Makini Link with connection_id.

Activate and deactivate#

A deactivated connection keeps its credentials and its data, but it stops working: /v4 and MCP answer 403, and it doesn't sync. Activating it resumes everything at once.
The answer is {"changed": true, "connection": {...}}. Asking for the state the connection is already in is safe: it answers changed: false and does nothing. Both directions are always allowed.

Delete a connection#

There are two ways to delete a connection.
Delete
DELETE /connections/{id}
The connection stops working at once and disappears from the API. Its magic link stops working too. Makini keeps its synced data for 30 days, then removes it.
Force delete
DELETE /connections/{id}/_force
The connection, its stored credentials and its data are removed immediately. This can't be undone. It also works on a connection you already deleted.
Both answer 204 with no body. Deleting a connection that is already gone is a 404.

Webhooks#

Each change above sends a webhook to the endpoints you registered in Settings → Webhooks. Changes made in the dashboard or in Makini Link send the same events.
EventSent when
connection.createdA connection is created.
connection.updatedA connection's details or credentials change.
connection.deletedA connection is deleted. data.deleted is soft or force. A force delete after a delete sends a second event.
Each event carries the connection in data.connection, in the same shape the API returns:
{
  "id": "0f7a3c52-9d1e-4b8a-a6f0-3e2d1c4b5a69",
  "type": "connection.updated",
  "occurredAt": "2026-09-25T10:30:00.000Z",
  "source": "management-api",
  "data": {
    "connection": { "id": "5b0c6f0e-2a4e-4a51-9d6c-1f3e8a7b2c90", "name": "Acme plant 2" }
  }
}
The connection in this example is shortened. For the other events, see Webhook events; for signatures and retries, see Verifying webhooks.
Modified at 2026-10-16 14:20:56
Previous
Management API authentication
Next
Managing your application
Built with