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.
Create a connection link
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 status | Reason | Next action |
|---|---|---|
| 403 | EMBEDDED_API_CATALOG_NOT_ENABLED | Configure the app or enable access to any app in Setup. |
| 404 | END_USER_NOT_FOUND | Check the stored MindCloud end-user ID and company. |
| 404 | CONNECTION_NOT_FOUND | Reload this end user's accounts and use an exact public ID. |
| 400 | CONNECTION_REQUIRED | Ask the user to connect an account. |
| 400 | CONNECTION_INVALID | Request a repair link for the account. |
| 409 | CONNECTION_CHOICE_REQUIRED | Ask the user to select an account, then pass its public ID. |
| 429 | RATE_LIMITED | Wait before retrying. |
| 503 | TEMPORARILY_UNAVAILABLE or END_USER_LOOKUP_UNAVAILABLE | Retry the request. Keep the existing end-user ID. |