SalesOS

Custom Actions

Your HTTPS endpoints as named actions for workflows, the copilot and record pages

Objects, their fields and the schema field types the editors offer

GET
/v1/custom-actions/meta

Authorization

AuthorizationRequiredBearer <token>

Session token from the SalesOS web app.

In: header

X-API-Key<token>

API key from Settings → API Keys. Authorization: ApiKey <key> is also accepted. Each operation lists the scope it needs under x-api-key-scopes.

In: header

curl -X GET "https://api.salesos.org/v1/custom-actions/meta" \
  -H "Authorization: Bearer <token>"

Actions a person may run from a record page of this object

GET
/v1/custom-actions/for-record

Authorization

AuthorizationRequiredBearer <token>

Session token from the SalesOS web app.

In: header

X-API-Key<token>

API key from Settings → API Keys. Authorization: ApiKey <key> is also accepted. Each operation lists the scope it needs under x-api-key-scopes.

In: header

Query Parameters

objectTypeRequiredstring
curl -X GET "https://api.salesos.org/v1/custom-actions/for-record?objectType=%3Cstring%3E" \
  -H "Authorization: Bearer <token>"

ManualCustomActionArray

[
  {
    "id": "string",
    "apiName": "string",
    "label": "string",
    "description": "string",
    "kind": "READ",
    "inputFields": [
      {
        "name": "string",
        "type": "string",
        "required": true,
        "description": "string",
        "enumValues": [
          "string"
        ]
      }
    ],
    "inputMapping": {},
    "outputMapping": {}
  }
]

List

GET
/v1/custom-actions

Authorization

AuthorizationRequiredBearer <token>

Session token from the SalesOS web app.

In: header

X-API-Key<token>

API key from Settings → API Keys. Authorization: ApiKey <key> is also accepted. Each operation lists the scope it needs under x-api-key-scopes.

In: header

curl -X GET "https://api.salesos.org/v1/custom-actions" \
  -H "Authorization: Bearer <token>"

CustomActionViewArray

[
  {
    "id": "string",
    "organizationId": "string",
    "apiName": "string",
    "label": "string",
    "description": "string",
    "url": "string",
    "inputSchema": null,
    "outputSchema": null,
    "kind": "string",
    "idempotent": true,
    "maxRetries": 0,
    "timeoutMs": 0,
    "objectTypes": [
      "string"
    ],
    "allowManual": true,
    "exposeAsTool": true,
    "toolDescription": "string",
    "inputMapping": null,
    "outputMapping": null,
    "isActive": true,
    "functionId": "string",
    "namedCredentialId": "string",
    "calloutPath": "string",
    "createdById": "string",
    "lastInvokedAt": "2019-08-24T14:15:22Z",
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z",
    "toolName": "string",
    "circuit": {
      "state": "CLOSED",
      "failures": 0,
      "retryAt": "2019-08-24T14:15:22Z"
    },
    "managedBy": {
      "installationId": "string",
      "componentId": "string",
      "appId": "string",
      "appName": "string",
      "appSlug": "string"
    }
  }
]

Register an action; the signing secret is returned once

POST
/v1/custom-actions

Authorization

AuthorizationRequiredBearer <token>

Session token from the SalesOS web app.

In: header

X-API-Key<token>

API key from Settings → API Keys. Authorization: ApiKey <key> is also accepted. Each operation lists the scope it needs under x-api-key-scopes.

In: header

Request Body

application/jsonRequired
apiNameRequiredstring

Stable identifier, also the copilot tool suffix

Pattern: "^[a-z][a-z0-9_]{1,47}$"
labelRequiredstring
Maximum length: 120
descriptionstring
Maximum length: 1000
urlstring

https:// endpoint that receives signed POSTs (omit when functionId is set)

Maximum length: 2048
functionIdstring

A serverless function that implements the action instead of an endpoint; null to switch back to url

Maximum length: 64
namedCredentialIdstring

A named credential to call instead of url: the request goes to its base URL + calloutPath with its auth. null to switch back to url

Maximum length: 64
calloutPathstring

Path under the named credential's base URL (default /)

Maximum length: 2048
inputSchemaRequiredobject

JSON Schema (object of scalar fields) for the request input

outputSchemaRequiredobject

JSON Schema (object of scalar fields) the response must match

kindRequiredstring

WRITE actions need confirmation in the copilot and approval for agents

Value in: "READ" | "WRITE"
idempotentboolean

Safe to repeat: enables retries (same Idempotency-Key)

maxRetriesnumber
Minimum: 0Maximum: 3
timeoutMsnumber
Default: 10000Minimum: 500Maximum: 30000
objectTypesarray<string>
allowManualboolean

Show a Run action button on record pages

exposeAsToolboolean

Offer the action to the copilot as a tool

toolDescriptionstring

What the assistant is told the tool does

Maximum length: 1000
inputMappingobject

{ inputName: "record.field" | { value } } for record runs

outputMappingobject

{ outputName: "recordField" } written back after record runs

isActiveboolean
curl -X POST "https://api.salesos.org/v1/custom-actions" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "apiName": "enrich_company",
    "label": "Enrich company",
    "description": "string",
    "url": "string",
    "functionId": "string",
    "namedCredentialId": "string",
    "calloutPath": "/v1/enrich",
    "inputSchema": {},
    "outputSchema": {},
    "kind": "READ",
    "idempotent": true,
    "maxRetries": 3,
    "timeoutMs": 10000,
    "objectTypes": [
      "ACCOUNT",
      "custom:invoice"
    ],
    "allowManual": true,
    "exposeAsTool": true,
    "toolDescription": "string",
    "inputMapping": {},
    "outputMapping": {
      "property1": "string",
      "property2": "string"
    },
    "isActive": true
  }'

CustomActionWithSecret

{
  "id": "string",
  "organizationId": "string",
  "apiName": "string",
  "label": "string",
  "description": "string",
  "url": "string",
  "inputSchema": null,
  "outputSchema": null,
  "kind": "string",
  "idempotent": true,
  "maxRetries": 0,
  "timeoutMs": 0,
  "objectTypes": [
    "string"
  ],
  "allowManual": true,
  "exposeAsTool": true,
  "toolDescription": "string",
  "inputMapping": null,
  "outputMapping": null,
  "isActive": true,
  "functionId": "string",
  "namedCredentialId": "string",
  "calloutPath": "string",
  "createdById": "string",
  "lastInvokedAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "toolName": "string",
  "secret": "string"
}

Get

GET
/v1/custom-actions/{id}

Authorization

AuthorizationRequiredBearer <token>

Session token from the SalesOS web app.

In: header

X-API-Key<token>

API key from Settings → API Keys. Authorization: ApiKey <key> is also accepted. Each operation lists the scope it needs under x-api-key-scopes.

In: header

Path Parameters

idRequiredstring
curl -X GET "https://api.salesos.org/v1/custom-actions/<string>" \
  -H "Authorization: Bearer <token>"

CustomActionView

{
  "id": "string",
  "organizationId": "string",
  "apiName": "string",
  "label": "string",
  "description": "string",
  "url": "string",
  "inputSchema": null,
  "outputSchema": null,
  "kind": "string",
  "idempotent": true,
  "maxRetries": 0,
  "timeoutMs": 0,
  "objectTypes": [
    "string"
  ],
  "allowManual": true,
  "exposeAsTool": true,
  "toolDescription": "string",
  "inputMapping": null,
  "outputMapping": null,
  "isActive": true,
  "functionId": "string",
  "namedCredentialId": "string",
  "calloutPath": "string",
  "createdById": "string",
  "lastInvokedAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "toolName": "string",
  "circuit": {
    "state": "CLOSED",
    "failures": 0,
    "retryAt": "2019-08-24T14:15:22Z"
  },
  "managedBy": {
    "installationId": "string",
    "componentId": "string",
    "appId": "string",
    "appName": "string",
    "appSlug": "string"
  }
}

Update

PATCH
/v1/custom-actions/{id}

Authorization

AuthorizationRequiredBearer <token>

Session token from the SalesOS web app.

In: header

X-API-Key<token>

API key from Settings → API Keys. Authorization: ApiKey <key> is also accepted. Each operation lists the scope it needs under x-api-key-scopes.

In: header

Request Body

application/jsonRequired
labelstring
Maximum length: 120
descriptionstring
Maximum length: 1000
urlstring

https:// endpoint that receives signed POSTs (omit when functionId is set)

Maximum length: 2048
functionIdstring

A serverless function that implements the action instead of an endpoint; null to switch back to url

Maximum length: 64
namedCredentialIdstring

A named credential to call instead of url: the request goes to its base URL + calloutPath with its auth. null to switch back to url

Maximum length: 64
calloutPathstring

Path under the named credential's base URL (default /)

Maximum length: 2048
inputSchemaobject

JSON Schema (object of scalar fields) for the request input

outputSchemaobject

JSON Schema (object of scalar fields) the response must match

kindstring

WRITE actions need confirmation in the copilot and approval for agents

Value in: "READ" | "WRITE"
idempotentboolean

Safe to repeat: enables retries (same Idempotency-Key)

maxRetriesnumber
Minimum: 0Maximum: 3
timeoutMsnumber
Default: 10000Minimum: 500Maximum: 30000
objectTypesarray<string>
allowManualboolean

Show a Run action button on record pages

exposeAsToolboolean

Offer the action to the copilot as a tool

toolDescriptionstring

What the assistant is told the tool does

Maximum length: 1000
inputMappingobject

{ inputName: "record.field" | { value } } for record runs

outputMappingobject

{ outputName: "recordField" } written back after record runs

isActiveboolean

Path Parameters

idRequiredstring

Header Parameters

Idempotency-Keystring

Unique key (a UUID is ideal) that makes this write safe to retry for 24 hours: a retry with the same body replays the original response (Idempotent-Replayed: true); the same key with a different body is a 409.

Maximum length: 255
curl -X PATCH "https://api.salesos.org/v1/custom-actions/<string>" \
  -H "Idempotency-Key: <string>" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Enrich company",
    "description": "string",
    "url": "string",
    "functionId": "string",
    "namedCredentialId": "string",
    "calloutPath": "/v1/enrich",
    "inputSchema": {},
    "outputSchema": {},
    "kind": "READ",
    "idempotent": true,
    "maxRetries": 3,
    "timeoutMs": 10000,
    "objectTypes": [
      "ACCOUNT",
      "custom:invoice"
    ],
    "allowManual": true,
    "exposeAsTool": true,
    "toolDescription": "string",
    "inputMapping": {},
    "outputMapping": {
      "property1": "string",
      "property2": "string"
    },
    "isActive": true
  }'

CustomActionView

{
  "id": "string",
  "organizationId": "string",
  "apiName": "string",
  "label": "string",
  "description": "string",
  "url": "string",
  "inputSchema": null,
  "outputSchema": null,
  "kind": "string",
  "idempotent": true,
  "maxRetries": 0,
  "timeoutMs": 0,
  "objectTypes": [
    "string"
  ],
  "allowManual": true,
  "exposeAsTool": true,
  "toolDescription": "string",
  "inputMapping": null,
  "outputMapping": null,
  "isActive": true,
  "functionId": "string",
  "namedCredentialId": "string",
  "calloutPath": "string",
  "createdById": "string",
  "lastInvokedAt": "2019-08-24T14:15:22Z",
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "toolName": "string",
  "circuit": {
    "state": "CLOSED",
    "failures": 0,
    "retryAt": "2019-08-24T14:15:22Z"
  },
  "managedBy": {
    "installationId": "string",
    "componentId": "string",
    "appId": "string",
    "appName": "string",
    "appSlug": "string"
  }
}

Remove

DELETE
/v1/custom-actions/{id}

Authorization

AuthorizationRequiredBearer <token>

Session token from the SalesOS web app.

In: header

X-API-Key<token>

API key from Settings → API Keys. Authorization: ApiKey <key> is also accepted. Each operation lists the scope it needs under x-api-key-scopes.

In: header

Path Parameters

idRequiredstring
curl -X DELETE "https://api.salesos.org/v1/custom-actions/<string>" \
  -H "Authorization: Bearer <token>"

DeletedResponse

{
  "deleted": true
}

Replace the signing secret (returned once)

POST
/v1/custom-actions/{id}/rotate-secret

Authorization

AuthorizationRequiredBearer <token>

Session token from the SalesOS web app.

In: header

X-API-Key<token>

API key from Settings → API Keys. Authorization: ApiKey <key> is also accepted. Each operation lists the scope it needs under x-api-key-scopes.

In: header

Path Parameters

idRequiredstring
curl -X POST "https://api.salesos.org/v1/custom-actions/<string>/rotate-secret" \
  -H "Authorization: Bearer <token>"

SecretResponse

{
  "secret": "string"
}

Call the endpoint with sample input; returns the request and response

POST
/v1/custom-actions/{id}/test

Authorization

AuthorizationRequiredBearer <token>

Session token from the SalesOS web app.

In: header

X-API-Key<token>

API key from Settings → API Keys. Authorization: ApiKey <key> is also accepted. Each operation lists the scope it needs under x-api-key-scopes.

In: header

Request Body

application/jsonRequired
inputobject

Sample input (validated against the input schema)

Path Parameters

idRequiredstring

Header Parameters

Idempotency-Keystring

Unique key (a UUID is ideal) that makes this write safe to retry for 24 hours: a retry with the same body replays the original response (Idempotent-Replayed: true); the same key with a different body is a 409.

Maximum length: 255
curl -X POST "https://api.salesos.org/v1/custom-actions/<string>/test" \
  -H "Idempotency-Key: <string>" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {}
  }'

ActionRunResult

{
  "invocationId": "string",
  "ok": true,
  "status": "SUCCEEDED",
  "output": {},
  "statusCode": 0,
  "latencyMs": 0,
  "attempts": 0,
  "errorCode": "string",
  "errorMessage": "string",
  "requestHeaders": {
    "property1": "string",
    "property2": "string"
  },
  "requestBody": {},
  "responseBody": "string"
}

Run the action on a record (record inputs mapped, outputs written back)

POST
/v1/custom-actions/{id}/run

Authorization

AuthorizationRequiredBearer <token>

Session token from the SalesOS web app.

In: header

X-API-Key<token>

API key from Settings → API Keys. Authorization: ApiKey <key> is also accepted. Each operation lists the scope it needs under x-api-key-scopes.

In: header

Request Body

application/jsonRequired
objectTypeRequiredstring

LEAD | CONTACT | ACCOUNT | OPPORTUNITY | TASK | custom:

recordIdRequiredstring
inputobject

Values for inputs the record mapping does not fill

Path Parameters

idRequiredstring

Header Parameters

Idempotency-Keystring

Unique key (a UUID is ideal) that makes this write safe to retry for 24 hours: a retry with the same body replays the original response (Idempotent-Replayed: true); the same key with a different body is a 409.

Maximum length: 255
curl -X POST "https://api.salesos.org/v1/custom-actions/<string>/run" \
  -H "Idempotency-Key: <string>" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "objectType": "ACCOUNT",
    "recordId": "string",
    "input": {}
  }'

ManualActionRunResult

{
  "invocationId": "string",
  "ok": true,
  "status": "SUCCEEDED",
  "output": {},
  "statusCode": 0,
  "latencyMs": 0,
  "attempts": 0,
  "errorCode": "string",
  "errorMessage": "string",
  "requestHeaders": {
    "property1": "string",
    "property2": "string"
  },
  "requestBody": {},
  "responseBody": "string",
  "applied": [
    "string"
  ],
  "writeError": "string"
}

Invocations page

GET
/v1/custom-actions/{id}/invocations

Authorization

AuthorizationRequiredBearer <token>

Session token from the SalesOS web app.

In: header

X-API-Key<token>

API key from Settings → API Keys. Authorization: ApiKey <key> is also accepted. Each operation lists the scope it needs under x-api-key-scopes.

In: header

Path Parameters

idRequiredstring

Query Parameters

pagestring
Default: 1
limitstring
Default: 20
statusstring
Value in: "SUCCEEDED" | "FAILED" | "TIMEOUT" | "BLOCKED" | "REJECTED" | "CIRCUIT_OPEN"
curl -X GET "https://api.salesos.org/v1/custom-actions/<string>/invocations?page=1&limit=20&status=SUCCEEDED" \
  -H "Authorization: Bearer <token>"

ExtensionInvocationPage

{
  "data": [
    {
      "id": "string",
      "organizationId": "string",
      "kind": "string",
      "customActionId": "string",
      "beforeSaveHookId": "string",
      "source": "string",
      "status": "string",
      "objectType": "string",
      "recordId": "string",
      "userId": "string",
      "requestUrl": "string",
      "requestHeaders": null,
      "requestBody": null,
      "statusCode": 0,
      "responseBody": "string",
      "errorCode": "string",
      "errorMessage": "string",
      "latencyMs": 0,
      "attempts": 0,
      "outcome": null,
      "replayOfId": "string",
      "createdAt": "2019-08-24T14:15:22Z"
    }
  ],
  "total": 0,
  "page": 0,
  "limit": 0,
  "totalPages": 0,
  "retentionDays": 0
}

Invocation

GET
/v1/custom-actions/{id}/invocations/{invocationId}

Authorization

AuthorizationRequiredBearer <token>

Session token from the SalesOS web app.

In: header

X-API-Key<token>

API key from Settings → API Keys. Authorization: ApiKey <key> is also accepted. Each operation lists the scope it needs under x-api-key-scopes.

In: header

Path Parameters

idRequiredstring
invocationIdRequiredstring
curl -X GET "https://api.salesos.org/v1/custom-actions/<string>/invocations/<string>" \
  -H "Authorization: Bearer <token>"

ExtensionInvocation

{
  "id": "string",
  "organizationId": "string",
  "kind": "string",
  "customActionId": "string",
  "beforeSaveHookId": "string",
  "source": "string",
  "status": "string",
  "objectType": "string",
  "recordId": "string",
  "userId": "string",
  "requestUrl": "string",
  "requestHeaders": null,
  "requestBody": null,
  "statusCode": 0,
  "responseBody": "string",
  "errorCode": "string",
  "errorMessage": "string",
  "latencyMs": 0,
  "attempts": 0,
  "outcome": null,
  "replayOfId": "string",
  "createdAt": "2019-08-24T14:15:22Z"
}

Send the same input again (new invocation id; no record write-back)

POST
/v1/custom-actions/{id}/invocations/{invocationId}/replay

Authorization

AuthorizationRequiredBearer <token>

Session token from the SalesOS web app.

In: header

X-API-Key<token>

API key from Settings → API Keys. Authorization: ApiKey <key> is also accepted. Each operation lists the scope it needs under x-api-key-scopes.

In: header

Path Parameters

idRequiredstring
invocationIdRequiredstring

Header Parameters

Idempotency-Keystring

Unique key (a UUID is ideal) that makes this write safe to retry for 24 hours: a retry with the same body replays the original response (Idempotent-Replayed: true); the same key with a different body is a 409.

Maximum length: 255
curl -X POST "https://api.salesos.org/v1/custom-actions/<string>/invocations/<string>/replay" \
  -H "Idempotency-Key: <string>" \
  -H "Authorization: Bearer <token>"

ActionRunResult

{
  "invocationId": "string",
  "ok": true,
  "status": "SUCCEEDED",
  "output": {},
  "statusCode": 0,
  "latencyMs": 0,
  "attempts": 0,
  "errorCode": "string",
  "errorMessage": "string",
  "requestHeaders": {
    "property1": "string",
    "property2": "string"
  },
  "requestBody": {},
  "responseBody": "string"
}