Docs

Connect end-user apps

Let your users connect published apps and run actions with their own accounts.

Choose app access

Open Embedded > Embedded API > Setup in MindCloud. Turn on Allow users to connect any app via API to connect apps without preparing an integration first. MindCloud Embedded must also be enabled for your company.

The switch starts off. Enabling it creates no integrations or installations. MindCloud prepares an integration when you request a connection link for an app. Existing integrations and SDK connection flows remain available.

The MCP server has its own switch under Embedded > Home. Each switch controls its own connection links. Turning API catalog access off limits new REST links to configured single-app connect integrations. Create an integration or confirm an older integration in its Setup tab to configure it for API access. Apps connected through catalog access do not become configured integrations automatically. Embedded API remains available, and users can still connect configured apps. Existing accounts remain available for reads and action runs while Embedded is enabled.

Identify the user

Create an end user through POST /v1/users and save the returned MindCloud userId on your server. Use that ID as endUserId below. Bind it to the signed-in user in your application before each request. Keep your MindCloud API key on your server.

An API key can address end users only in its own company. X-Company-Id cannot change this company scope.

Find an app slug or ID through GET /v2/universal/apps. Request a link with an API key that holds embedded:create:

curl -X POST \
  "https://connect.mindcloud.co/v2/embedded/end-users/$END_USER_ID/connect-links" \
  -H "Authorization: Bearer $MINDCLOUD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"appRef":"slack"}'

The response is 201 Created:

{
  "success": true,
  "data": {
    "url": "https://app.mindcloud.co/embedded-install#t=<token>&channel=api",
    "appName": "Slack",
    "expiresOn": "2026-10-01T12:15:00.000Z",
    "singleUse": true
  }
}

Show the returned URL only to this end user. Whoever opens it can connect an account as that end user. Use the URL exactly as returned, including its fragment. The link lasts fifteen minutes and works once. Each end user can request ten REST links per minute.

The hosted page opens the Embedded connection flow. Its thirty-minute session has the existing scope for that end user and installation. For repair, that installation can include the other apps in its existing integration. If a failure occurs after the link is consumed, request a new link.

List connected accounts

Use an API key that holds embedded:view:

curl \
  "https://connect.mindcloud.co/v2/embedded/end-users/$END_USER_ID/connections?limit=100&offset=0" \
  -H "Authorization: Bearer $MINDCLOUD_API_KEY"
{
  "success": true,
  "data": [
    {
      "id": "Cn6vH3jW8qYt",
      "appSlug": "slack",
      "appName": "Slack",
      "label": "Support workspace",
      "status": "valid",
      "connectedOn": "2026-10-01T12:05:00.000Z"
    }
  ],
  "meta": {
    "pagination": {
      "totalCount": 1,
      "totalCountExact": true,
      "hasNextPage": false,
      "hasPreviousPage": false
    }
  }
}

The list follows the standard list grammar: limit 1–1000 (default 100), offset, sort, fields, and filters such as appSlug=slack. The list includes existing SDK and MCP accounts owned by this end user. It contains public IDs and account information only. Pass an account's id as connectionId in the calls below.

Run an action

Use an API key that holds the Universal permission for the action's operation (universal:read for lookups and read actions). Add endUserId to the existing Universal action request. Pass the selected public connectionId when the user has several usable accounts:

curl -X POST \
  "https://connect.mindcloud.co/v2/universal/apps/slack/actions/send-channel-message/run" \
  -H "Authorization: Bearer $MINDCLOUD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endUserId": "enduser_GhSUEYhipn4g",
    "connectionId": "Cn6vH3jW8qYt",
    "arguments": {"channel":"C123","text":"Hello"}
  }'

The API uses only this end user's connected accounts. It accepts the exact public connection ID from the list. It does not accept labels, internal credential IDs, or default as a REST connection ID. Without an ID, it selects the sole usable account. Several usable accounts return 409 with reason CONNECTION_CHOICE_REQUIRED and the public choices in error.details.candidates:

{
  "success": false,
  "error": {
    "code": "CONFLICT",
    "message": "Select a connectionId for this end user and retry.",
    "details": {
      "reason": "CONNECTION_CHOICE_REQUIRED",
      "candidates": [
        { "id": "Cn6vH3jW8qYt", "label": "Support workspace", "status": "valid" },
        { "id": "Hp2rT8kW5nZc", "label": "Sales workspace", "status": "valid" }
      ]
    }
  }
}

Select an account and retry with its id as connectionId. When the provider itself refuses the action, the run returns 502 with code PROVIDER_ERROR, the provider's code in details.reason, and its HTTP status in details.provider.status. MindCloud's own refusals before the provider call keep their own code, such as 404 NOT_FOUND.

REST action execution requires a connected account, including apps without authentication. The existing installationId request remains supported. Use it separately from connectionId.

Resolve lookup choices

Use the same endUserId and selected account for provider lookups:

curl \
  "https://connect.mindcloud.co/v2/universal/apps/slack/actions/send-channel-message/lookups/channel?endUserId=$END_USER_ID&connectionId=$CONNECTION_ID&q=support" \
  -H "Authorization: Bearer $MINDCLOUD_API_KEY"

This prevents dropdown choices from using a company account. End-user ownership is checked for fixed choices too.

Repair an account

Request a new connection link with its public ID:

{
  "appRef": "slack",
  "connectionId": "Cn6vH3jW8qYt"
}

For an SDK account, repair keeps its installation and integration settings and updates that account. For a provisioned account without an installation, the SDK creates a new account and keeps the original credential. After authentication, reload the connection list and use the new account's public id. The original ID still selects the provisioned credential.

Handle failures

Errors use the standard envelope. The codes below are error.details.reason; error.code is fixed by the status (FORBIDDEN, NOT_FOUND, VALIDATION_FAILED, CONFLICT, RATE_LIMITED, UNAVAILABLE).

HTTP statusReasonNext action
403EMBEDDED_API_CATALOG_NOT_ENABLEDConfigure the app or enable access to any app in Setup.
404END_USER_NOT_FOUNDCheck the stored MindCloud end-user ID and company.
404CONNECTION_NOT_FOUNDReload this end user's accounts and use an exact public ID.
400CONNECTION_REQUIREDAsk the user to connect an account.
400CONNECTION_INVALIDRequest a repair link for the account.
409CONNECTION_CHOICE_REQUIREDAsk the user to select an account, then pass its public ID.
429RATE_LIMITEDWait before retrying.
503TEMPORARILY_UNAVAILABLE or END_USER_LOOKUP_UNAVAILABLERetry the request. Keep the existing end-user ID.