Documentation Index
Fetch the complete documentation index at: https://docs.getmembrane.com/llms.txt
Use this file to discover all available pages before exploring further.
An action is a single operation your agent or app performs in an external app: create a contact, send a message, list invoices, update a deal. Actions are the primary way to interact with connected apps through Membrane.
Running actions
Running an action means calling /act — Membrane’s unified entry point for operating on an external app through a connection. One endpoint, one shape, multiple surfaces:
| Way to Use | How to Run |
|---|
| CLI | membrane act --connectionKey <key> --api '{"method":"POST","path":"/..."}' --json |
| MCP | Use the act tool with one of api / code / key / id |
| API | POST /act with the dispatch in the body |
| Console | Action → Run (test with sample input) |
Every response is { output, actionRunId }. On failure the body still carries actionRunId — feed it to GET /action-run-logs/{id} for the resolved action, mapped input, errors, and the raw HTTP exchange.
What goes into /act
Three dispatch styles, exactly one per call. Pick the one that fits the work:
api — inline HTTP request
A raw HTTP request sent through the connection’s auth and base URL. Default building block for ad-hoc work.
{
"connectionKey": "hubspot-prod",
"api": {
"method": "POST",
"path": "/crm/v3/objects/contacts",
"body": { "properties": { "email": "jane@example.com" } }
}
}
code — sandboxed JavaScript
A JS snippet run in a sandbox with an authenticated membrane client, connection, and integration pre-wired. Good for multi-step composites that don’t map to a single HTTP call.
{
"connectionKey": "hubspot-prod",
"code": "module.exports = async ({ input, membrane }) => { const me = await membrane.proxy.get('/account-info'); return { portalId: me.data.portalId, ...input }; }",
"input": { "tag": "qa" }
}
Reusable action
A named action Membrane runs on your behalf. Address it by key when the action has one (saved actions); use id when it doesn’t (catalog actions have no key). Membrane owns the vendor-specific request shape, auth scoping, and retries.
{
"key": "create-contact",
"integrationKey": "hubspot",
"connectionKey": "hubspot-prod",
"input": { "email": "jane@example.com" }
}
api and code always need a connection (via connectionKey or connectionId). Reusable actions route through the action’s own scope, which may bind a specific connection or integration — so the connection field becomes optional when the scope already resolves one.
Input is validated against the action’s inputSchema. Extra properties are silently ignored.
Reusable actions
When you find yourself about to make the same /act call a second time, save it as a reusable action. Future calls become { key: "<your-key>" } instead of the full inline spec, and the action is inspectable in the workspace later.
Finding
Describe what you want to do and Membrane finds matching actions. You can search by intent across your workspace and connected apps.
| Way to Use | How to Find |
|---|
| CLI | membrane action list --connectionId <id> --intent "create a contact" |
| MCP | Use the list-actions tool with intent parameter |
| API | GET /actions?connectionId=<id>&intent=create+a+contact |
| SDK | membrane.actions.find({ connectionId: '<id>', intent: 'create a contact' }) |
| Console | Actions page — browse and search |
Creating
Create actions from an intent — describe what the action should do and Membrane configures it automatically.
| Way to Use | How to Create |
|---|
| CLI | membrane action create "create a task" --connectionId <id> |
| MCP | Use the create-action tool |
| API | POST /actions with { "intent": "create a task", "connectionId": "<id>" } |
| SDK | membrane.actions.create({ intent: 'create a task', connectionId: '<id>' }) |
| Console | Actions → Create Action |
The action enters a BUILDING state while Membrane configures it. Use --wait (CLI) or ?wait=true (API) to wait until ready.
Updating
Update an action’s configuration.
| Way to Use | How to Update |
|---|
| API | PATCH /actions/<actionId> |
| SDK | membrane.action('<actionId>').patch({ ... }) |
| Console | Action → Edit |
Deleting
Archive an action to remove it.
| Way to Use | How to Delete |
|---|
| API | DELETE /actions/<actionId> |
| SDK | membrane.action('<actionId>').archive() |
| Console | Action → Archive |
Action Types
Actions map to function types that determine what happens when they run:
| Type | Description |
|---|
api-request-to-external-app | Make API requests with automatic authentication |
api-request-to-your-app | Make an API request to your backend |
run-javascript | Run custom JavaScript/TypeScript logic |
http-request | Make arbitrary HTTP requests |
Run logs and replay
All action runs are recorded in Action Run Logs — input, output, duration, errors, and the raw HTTP exchange.
Each log carries an action snapshot — the complete /act body that was used. POST it back to /act to replay the same dispatch:
SNAPSHOT=$(curl -s https://api.integration.app/action-run-logs/<runId> \
-H "Authorization: Bearer $TOKEN" | jq '.action')
curl -X POST https://api.integration.app/act \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "$SNAPSHOT"
Override input or connectionKey in the snapshot to vary the call:
curl -X POST https://api.integration.app/act \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "$(echo "$SNAPSHOT" | jq '.input.email = "updated@example.com"')"