Crossing Edge API

Build on Crossing Edge

Read and change everything in a workspace from your own systems. Every call runs with the access of the member who made the key, and every change shows in the record’s history.

159operations
v1stable
OpenAPI 3.1for any client
120/minper key

Introduction

The Crossing Edge API reads and changes everything in a workspace from your own systems: contacts, companies, deals and any object you added, tasks and calls, email, Telegram, webhooks, reports and settings.

It is a JSON API over HTTPS. Every operation runs with the access of the member who made the key, through the same checks as the app: automations run, duplicates are caught, and every change shows in the record’s history, marked via the API.

Base URLhttps://api.crossingedge.com/v1

There are two ways to call it. REST routes cover the records most integrations need. Actions (POST /actions/{name}) reach every other operation, the same set the Crossing Edge MCP server offers. Both share keys, limits and errors.

curl https://api.crossingedge.com/v1/me \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/me", {
  headers: { Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}` },
});
console.log(await res.json());
import os, requests

res = requests.get("https://api.crossingedge.com/v1/me",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"})
print(res.json())

Authentication

Send a workspace API key as a bearer token on every request:

Authorization: Bearer ce_live_…

Make keys in Crossing Edge under Settings › Integrations › API. Each key is shown once: store it in a secret manager or an environment variable. Crossing Edge keeps only a hash.

  • Read only keys run reading operations. Anything that changes data answers 403 insufficient_scope.
  • Read and write keys run everything their maker can do, and nothing more.
  • A key can expire after 30, 90 or 365 days, and can be revoked at any time.
  • A key stops working if the member who made it leaves the workspace or loses the “Make API keys” access.
Server-side only. Never put a key in a web page or a mobile app. The API sends no CORS headers, so browsers cannot read its answers.

Requests and responses

Send bodies as JSON with Content-Type: application/json, up to 1 MB. Unknown fields are refused rather than ignored, so a typo never silently does nothing.

Every success answers { "data": …, "request_id": "req_…" }, with 201 for a created record. Every response carries an X-Request-Id header; quote it when asking for help.

Records take field values by key or label. Call GET /schema for every object, field and the choices a field allows. Owners are given as a member’s email.

Lists answer up to limit records (at most 100) with the total that match. Narrow them with query, owner or a status; for every record of an object at once, use the export_records action.

Errors

Errors use HTTP status codes and one shape:

{
  "error": {
    "type": "invalid_request",
    "code": "invalid_parameter",
    "message": "firstName is required",
    "field": "firstName",
    "request_id": "req_7c1f0e2a9b4d"
  }
}
StatusTypeMeans
400invalid_requestA missing or wrong field, or bad JSON. field names it.
401authentication_errorNo key, or one that is unknown, revoked or expired.
403permission_errorThe key may not do this: read only, its maker lacks the access, or it is suspended.
404not_foundThe record or the operation is not there.
409conflictIt clashes with what exists, like a duplicate email.
422invalid_requestAn Idempotency-Key reused for a different request.
429rate_limitedOver a limit. Wait Retry-After seconds.
5xxserver_errorOur side failed. Retry with backoff.

Rate limits

Each key may make 120 requests a minute and 25,000 a day (UTC). Every response says where you stand:

HeaderValue
X-RateLimit-LimitRequests a minute
X-RateLimit-RemainingLeft this minute
X-RateLimit-ResetSeconds until the minute resets
X-Daily-LimitRequests a day
X-Daily-RemainingLeft today
Retry-AfterOn a 429: seconds to wait

On a 429, wait for Retry-After, then retry. For other failures, retry with exponential backoff and jitter, and only writes that carry an Idempotency-Key.

Idempotency

Networks fail mid-request. Send an Idempotency-Key header (any unique string, like a UUID) with every write, and retry with the same key: for 24 hours, a retry returns the first answer, marked Idempotent-Replayed: true, instead of creating a second record.

Reusing a key for a different request answers 422 idempotency_conflict.

Versioning and changes

The version is in the path: /v1. Within v1 we only add: new operations, new optional fields, new fields in answers. Write clients that ignore fields they do not know. Anything that would break a client comes as a new version, announced ahead.

The full description is OpenAPI 3.1: import it into Postman or Insomnia, or generate a client from it.

MCP

Connecting an AI assistant, IDE or agent rather than writing code? The same operations are an MCP server at https://app.crossingedge.com/mcp. It signs in through the browser or takes a key in a header. See Settings › Integrations › MCP.

Security

  • HTTPS only, with HSTS. Keys are stored as SHA-256 hashes and shown once.
  • Use a read-only key wherever writing is not needed, and one key per system, so one can be revoked alone.
  • Every request is logged for 30 days (method, path, status, time; never bodies) and visible to the workspace in Settings › Integrations › API.
  • Revoke a key that may have leaked straight away, then make a new one.

Getting started

Check a key.

GET/me

The key in use

Read key

Which key this is, its scope, the workspace it works in, and the member it acts as. A cheap way to check a key works.

curl -X GET "https://api.crossingedge.com/v1/me" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/me", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.get(
    "https://api.crossingedge.com/v1/me",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Contacts

REST routes for contacts.

GET/contacts

List or search contacts

Read key

Finds contacts by name, email, phone, job title or company, optionally narrowed by status or owner. Returns compact rows with ids; use get_contact for everything about one.

Query parameters

querystring

Words to match in the name, email, phone, job title or company names

statusstring

Only this lifecycle status

ownerstring

Only contacts this member owns, by email or name

companyIdnumber

Only contacts at this company

limitnumber

How many to return, default 20, at most 100

curl -X GET "https://api.crossingedge.com/v1/contacts" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/contacts", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.get(
    "https://api.crossingedge.com/v1/contacts",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "total": 1,
    "…": [
      {
        "id": 101,
        "…": "…"
      }
    ]
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/contacts

Create a contact

Read and write keyIdempotency-Key

Adds a contact. Needs a first name and an email or phone. Runs the workspace’s automations and duplicate check like a contact made in the app.

Body

firstNamestringrequired

First name

lastNamestring

Last name

emailstring

Email. A contact needs an email or a phone

phonestring

Phone, with country code

jobTitlestring

Job title

statusstring

Lifecycle status, one of the choices get_schema lists for contacts.status

sourcestring

Where they came from, one of the choices get_schema lists for contacts.source

linkedinstring

LinkedIn profile URL

telegramstring

Telegram username, like @priya

countrystring

Country they are based in, by name or two-letter code (India, IN)

statestring

Their state, province or region

citystring

Their city

ownerstring

Owner, by member email or name

companyIdsarray of number

Companies they work with, by id (replaces the current set)

companyNamestring

A company to link by exact name; made if the workspace has none by that name

customobject

Custom field values by field key (keys from get_schema)

curl -X POST "https://api.crossingedge.com/v1/contacts" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "firstName": "Priya"
}'
const res = await fetch("https://api.crossingedge.com/v1/contacts", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "firstName": "Priya"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/contacts",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "firstName": "Priya"
    },
)
data = res.json()["data"]
Response · 201
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
GET/contacts/{id}

Get a contact

Read key

Everything about one contact: their fields, companies, owner, and their latest activities and open tasks.

Path parameters

idstringrequired

The record id

curl -X GET "https://api.crossingedge.com/v1/contacts/101" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/contacts/101", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.get(
    "https://api.crossingedge.com/v1/contacts/101",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
PATCH/contacts/{id}

Update a contact

Read and write keyIdempotency-Key

Changes a contact. Only the fields passed change; companyName adds a company link, companyIds replaces the set.

Path parameters

idstringrequired

The record id

Body

firstNamestring

First name

lastNamestring

Last name

emailstring

Email. A contact needs an email or a phone

phonestring

Phone, with country code

jobTitlestring

Job title

statusstring

Lifecycle status, one of the choices get_schema lists for contacts.status

sourcestring

Where they came from, one of the choices get_schema lists for contacts.source

linkedinstring

LinkedIn profile URL

telegramstring

Telegram username, like @priya

countrystring

Country they are based in, by name or two-letter code (India, IN)

statestring

Their state, province or region

citystring

Their city

ownerstring

Owner, by member email or name

companyIdsarray of number

Companies they work with, by id (replaces the current set)

companyNamestring

A company to link by exact name; made if the workspace has none by that name

customobject

Custom field values by field key (keys from get_schema)

curl -X PATCH "https://api.crossingedge.com/v1/contacts/101" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "firstName": "Priya",
  "lastName": "Nair"
}'
const res = await fetch("https://api.crossingedge.com/v1/contacts/101", {
  method: "PATCH",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "firstName": "Priya",
    "lastName": "Nair"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.patch(
    "https://api.crossingedge.com/v1/contacts/101",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "firstName": "Priya",
      "lastName": "Nair"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
DELETE/contacts/{id}

Delete a contact

Read and write key

Deletes a contact for good, with their notes and history. Ask the person first, then call with confirm: true. Deleting is permanent.

Path parameters

idstringrequired

The record id

curl -X DELETE "https://api.crossingedge.com/v1/contacts/101" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/contacts/101", {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.delete(
    "https://api.crossingedge.com/v1/contacts/101",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "deleted": true
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Companies

REST routes for companies.

GET/companies

List or search companies

Read key

Finds records of any object (companies, deals, contacts or a workspace object) by words in their name and fields, optionally narrowed by owner. Compact rows with ids; get_record has everything about one.

Query parameters

querystring

Words to match

ownerstring

Only records this member owns, by email or name

limitnumber

How many, default 20, at most 100

curl -X GET "https://api.crossingedge.com/v1/companies" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/companies", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.get(
    "https://api.crossingedge.com/v1/companies",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "total": 1,
    "…": [
      {
        "id": 101,
        "…": "…"
      }
    ]
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/companies

Create a company

Read and write keyIdempotency-Key

Adds a record of any object: a company, a deal (lands in the default pipeline unless pipeline or stage is given), a contact, or a workspace object. Runs automations and duplicate checks like the app.

Body

Field values by key or label: name, domain, amount, owner (member email), and custom fields by their label. /schema lists every field and its choices.

curl -X POST "https://api.crossingedge.com/v1/companies" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Acme",
  "domain": "acme.com"
}'
const res = await fetch("https://api.crossingedge.com/v1/companies", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "name": "Acme",
    "domain": "acme.com"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/companies",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "name": "Acme",
      "domain": "acme.com"
    },
)
data = res.json()["data"]
Response · 201
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
GET/companies/{id}

Get a company

Read key

Everything about one record of any object: its fields, what it is linked to (companies, people, deals, parents and subsidiaries, workspace relationships), and its latest activity and notes.

Path parameters

idstringrequired

The record id

curl -X GET "https://api.crossingedge.com/v1/companies/101" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/companies/101", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.get(
    "https://api.crossingedge.com/v1/companies/101",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
PATCH/companies/{id}

Update a company

Read and write keyIdempotency-Key

Changes a record of any object. Only the fields passed change; a deal moves stage by passing stage (and pipeline if it is in several). companyIds and contactIds replace the set; link_records adds or removes one.

Path parameters

idstringrequired

The record id

Body

Field values by key or label: name, domain, amount, owner (member email), and custom fields by their label. /schema lists every field and its choices.

curl -X PATCH "https://api.crossingedge.com/v1/companies/101" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Acme",
  "domain": "acme.com"
}'
const res = await fetch("https://api.crossingedge.com/v1/companies/101", {
  method: "PATCH",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "name": "Acme",
    "domain": "acme.com"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.patch(
    "https://api.crossingedge.com/v1/companies/101",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "name": "Acme",
      "domain": "acme.com"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
DELETE/companies/{id}

Delete a company

Read and write key

Deletes a record of any object for good, with its notes and history. Ask the person first, then call with confirm: true. Deleting is permanent.

Path parameters

idstringrequired

The record id

curl -X DELETE "https://api.crossingedge.com/v1/companies/101" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/companies/101", {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.delete(
    "https://api.crossingedge.com/v1/companies/101",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "deleted": true
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Deals

REST routes for deals.

GET/deals

List or search deals

Read key

Finds records of any object (companies, deals, contacts or a workspace object) by words in their name and fields, optionally narrowed by owner. Compact rows with ids; get_record has everything about one.

Query parameters

querystring

Words to match

ownerstring

Only records this member owns, by email or name

limitnumber

How many, default 20, at most 100

curl -X GET "https://api.crossingedge.com/v1/deals" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/deals", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.get(
    "https://api.crossingedge.com/v1/deals",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "total": 1,
    "…": [
      {
        "id": 101,
        "…": "…"
      }
    ]
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/deals

Create a deal

Read and write keyIdempotency-Key

Adds a record of any object: a company, a deal (lands in the default pipeline unless pipeline or stage is given), a contact, or a workspace object. Runs automations and duplicate checks like the app.

Body

Field values by key or label: name, domain, amount, owner (member email), and custom fields by their label. /schema lists every field and its choices.

curl -X POST "https://api.crossingedge.com/v1/deals" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Acme renewal",
  "amount": 12000,
  "stage": "Proposal"
}'
const res = await fetch("https://api.crossingedge.com/v1/deals", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "name": "Acme renewal",
    "amount": 12000,
    "stage": "Proposal"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/deals",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "name": "Acme renewal",
      "amount": 12000,
      "stage": "Proposal"
    },
)
data = res.json()["data"]
Response · 201
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
GET/deals/{id}

Get a deal

Read key

Everything about one record of any object: its fields, what it is linked to (companies, people, deals, parents and subsidiaries, workspace relationships), and its latest activity and notes.

Path parameters

idstringrequired

The record id

curl -X GET "https://api.crossingedge.com/v1/deals/101" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/deals/101", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.get(
    "https://api.crossingedge.com/v1/deals/101",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
PATCH/deals/{id}

Update a deal

Read and write keyIdempotency-Key

Changes a record of any object. Only the fields passed change; a deal moves stage by passing stage (and pipeline if it is in several). companyIds and contactIds replace the set; link_records adds or removes one.

Path parameters

idstringrequired

The record id

Body

Field values by key or label: name, domain, amount, owner (member email), and custom fields by their label. /schema lists every field and its choices.

curl -X PATCH "https://api.crossingedge.com/v1/deals/101" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Acme renewal",
  "amount": 12000,
  "stage": "Proposal"
}'
const res = await fetch("https://api.crossingedge.com/v1/deals/101", {
  method: "PATCH",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "name": "Acme renewal",
    "amount": 12000,
    "stage": "Proposal"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.patch(
    "https://api.crossingedge.com/v1/deals/101",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "name": "Acme renewal",
      "amount": 12000,
      "stage": "Proposal"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
DELETE/deals/{id}

Delete a deal

Read and write key

Deletes a record of any object for good, with its notes and history. Ask the person first, then call with confirm: true. Deleting is permanent.

Path parameters

idstringrequired

The record id

curl -X DELETE "https://api.crossingedge.com/v1/deals/101" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/deals/101", {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.delete(
    "https://api.crossingedge.com/v1/deals/101",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "deleted": true
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Any object

REST routes for any object.

GET/objects/{object}/records

List or search records of any object

Read key

Finds records of any object (companies, deals, contacts or a workspace object) by words in their name and fields, optionally narrowed by owner. Compact rows with ids; get_record has everything about one.

Path parameters

objectstringrequired

The object: companies, deals, contacts, or a workspace object’s id (obj_…, from /schema)

Query parameters

querystring

Words to match

ownerstring

Only records this member owns, by email or name

limitnumber

How many, default 20, at most 100

curl -X GET "https://api.crossingedge.com/v1/objects/deals/records" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/objects/deals/records", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.get(
    "https://api.crossingedge.com/v1/objects/deals/records",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "total": 1,
    "…": [
      {
        "id": 101,
        "…": "…"
      }
    ]
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/objects/{object}/records

Create a record

Read and write keyIdempotency-Key

Adds a record of any object: a company, a deal (lands in the default pipeline unless pipeline or stage is given), a contact, or a workspace object. Runs automations and duplicate checks like the app.

Path parameters

objectstringrequired

The object: companies, deals, contacts, or a workspace object’s id (obj_…, from /schema)

Body

Field values by key or label: name, domain, amount, owner (member email), and custom fields by their label. /schema lists every field and its choices.

curl -X POST "https://api.crossingedge.com/v1/objects/deals/records" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Example"
}'
const res = await fetch("https://api.crossingedge.com/v1/objects/deals/records", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "name": "Example"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/objects/deals/records",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "name": "Example"
    },
)
data = res.json()["data"]
Response · 201
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
GET/objects/{object}/records/{id}

Get a record

Read key

Everything about one record of any object: its fields, what it is linked to (companies, people, deals, parents and subsidiaries, workspace relationships), and its latest activity and notes.

Path parameters

objectstringrequired

The object: companies, deals, contacts, or a workspace object’s id (obj_…, from /schema)

idstringrequired

The record id

curl -X GET "https://api.crossingedge.com/v1/objects/deals/records/101" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/objects/deals/records/101", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.get(
    "https://api.crossingedge.com/v1/objects/deals/records/101",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
PATCH/objects/{object}/records/{id}

Update a record

Read and write keyIdempotency-Key

Changes a record of any object. Only the fields passed change; a deal moves stage by passing stage (and pipeline if it is in several). companyIds and contactIds replace the set; link_records adds or removes one.

Path parameters

objectstringrequired

The object: companies, deals, contacts, or a workspace object’s id (obj_…, from /schema)

idstringrequired

The record id

Body

Field values by key or label: name, domain, amount, owner (member email), and custom fields by their label. /schema lists every field and its choices.

curl -X PATCH "https://api.crossingedge.com/v1/objects/deals/records/101" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Example"
}'
const res = await fetch("https://api.crossingedge.com/v1/objects/deals/records/101", {
  method: "PATCH",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "name": "Example"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.patch(
    "https://api.crossingedge.com/v1/objects/deals/records/101",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "name": "Example"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
DELETE/objects/{object}/records/{id}

Delete a record

Read and write key

Deletes a record of any object for good, with its notes and history. Ask the person first, then call with confirm: true. Deleting is permanent.

Path parameters

objectstringrequired

The object: companies, deals, contacts, or a workspace object’s id (obj_…, from /schema)

idstringrequired

The record id

curl -X DELETE "https://api.crossingedge.com/v1/objects/deals/records/101" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/objects/deals/records/101", {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.delete(
    "https://api.crossingedge.com/v1/objects/deals/records/101",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "deleted": true
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Tasks

REST routes for tasks.

GET/tasks

List tasks and activities

Read key

Tasks, open ones by default: yours, everyone’s you can see, or those on one record. Also lists other activity types with type.

Query parameters

scopestring

Tasks you created or are on (default), or all you can see

statusstring

Default open

typestring

Default task

overdueboolean

Only those past due

dueBeforestring

Only those due before this ISO date

contactIdnumber

The contact it is about

companyIdnumber

The company it is about

dealIdnumber

The deal it is about

limitnumber

Default 25, at most 100

curl -X GET "https://api.crossingedge.com/v1/tasks" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/tasks", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.get(
    "https://api.crossingedge.com/v1/tasks",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "total": 1,
    "…": [
      {
        "id": 101,
        "…": "…"
      }
    ]
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/tasks

Create a task

Read and write keyIdempotency-Key

Plans a task: what, when it is due, how urgent, who owns it (you by default), and the records it is about. Pass parentTaskId to make it a sub-task.

Body

subjectstringrequired

What needs doing

duestringrequired

Due date and time, ISO 8601, e.g. 2026-10-01T17:00:00+05:30

prioritystring

Default Medium

One of Low Medium High

assigneestring

Who owns it, by member email or name. Default: you

bodystring

Details

parentTaskIdstring

Make it a sub-task inside this task; it then takes that task’s records

notifyarray of string

People to keep informed, by member email or name

contactIdnumber

The contact it is about

companyIdnumber

The company it is about

dealIdnumber

The deal it is about

recordsarray of object

Other records it is about, as { object, id } (custom objects too)

curl -X POST "https://api.crossingedge.com/v1/tasks" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "subject": "Call Priya about the renewal",
  "due": "2026-11-02T10:00:00Z"
}'
const res = await fetch("https://api.crossingedge.com/v1/tasks", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "subject": "Call Priya about the renewal",
    "due": "2026-11-02T10:00:00Z"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/tasks",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "subject": "Call Priya about the renewal",
      "due": "2026-11-02T10:00:00Z"
    },
)
data = res.json()["data"]
Response · 201
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
GET/tasks/{id}

Get a task

Read key

One task (or any activity) with everything logged inside it: its calls, meetings, emails, messages, notes and sub-tasks.

Path parameters

idstringrequired

The record id

curl -X GET "https://api.crossingedge.com/v1/tasks/101" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/tasks/101", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.get(
    "https://api.crossingedge.com/v1/tasks/101",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
PATCH/tasks/{id}

Update a task

Read and write keyIdempotency-Key

Changes a task or activity. Only what is passed changes. status: planned | in_progress | done | cancelled.

Path parameters

idstringrequired

The record id

Body

subjectstring

New subject

bodystring

New details

duestring

New due date, ISO 8601 (tasks), or when it happened (other types)

prioritystring

One of Low Medium High

statusstring

One of planned in_progress done cancelled

assigneestring

New owner, by member email or name

notifyarray of string

The full new list of people to keep informed, by email or name

detailsobject

Type fields to change

moveIntoTaskstring

Move it inside this task; it then takes that task’s records

moveOutOfTaskboolean

Take it out of the task it is in, keeping its records

contactIdnumber

The contact it is about. Passing any record replaces what it is linked to

companyIdnumber

The company it is about. Passing any record replaces what it is linked to

dealIdnumber

The deal it is about. Passing any record replaces what it is linked to

recordsarray of object

Other records it is about, as { object, id } (custom objects too). Passing any record replaces what it is linked to

curl -X PATCH "https://api.crossingedge.com/v1/tasks/101" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "subject": "Call Priya about the renewal",
  "body": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/tasks/101", {
  method: "PATCH",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "subject": "Call Priya about the renewal",
    "body": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.patch(
    "https://api.crossingedge.com/v1/tasks/101",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "subject": "Call Priya about the renewal",
      "body": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
DELETE/tasks/{id}

Delete a task

Read and write key

Deletes a task or activity for good; a task takes everything logged inside it. Ask the person first, then call with confirm: true. Deleting is permanent.

Path parameters

idstringrequired

The record id

curl -X DELETE "https://api.crossingedge.com/v1/tasks/101" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/tasks/101", {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.delete(
    "https://api.crossingedge.com/v1/tasks/101",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "deleted": true
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/tasks/{id}/complete

Complete a task

Read and write keyIdempotency-Key

Marks a task done.

Path parameters

idstringrequired

The record id

curl -X POST "https://api.crossingedge.com/v1/tasks/101/complete" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'
const res = await fetch("https://api.crossingedge.com/v1/tasks/101/complete", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({}),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/tasks/101/complete",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Schema

REST routes for schema.

GET/schema

Get the workspace schema: objects, fields and their choices

Read key

The workspace data model: every object and field (with types and choices), pipelines and stages, members, currency and today’s date.

curl -X GET "https://api.crossingedge.com/v1/schema" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY"
const res = await fetch("https://api.crossingedge.com/v1/schema", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
  },
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.get(
    "https://api.crossingedge.com/v1/schema",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Contacts and tasks

Actions

Contacts, tasks, calls, meetings and notes.

POST/actions/search_contacts

Search contacts

Read key

Finds contacts by name, email, phone, job title or company, optionally narrowed by status or owner. Returns compact rows with ids; use get_contact for everything about one.

Body

querystring

Words to match in the name, email, phone, job title or company names

statusstring

Only this lifecycle status

ownerstring

Only contacts this member owns, by email or name

companyIdnumber

Only contacts at this company

limitnumber

How many to return, default 20, at most 100

curl -X POST "https://api.crossingedge.com/v1/actions/search_contacts" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "query": "acme",
  "status": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/search_contacts", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "query": "acme",
    "status": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/search_contacts",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "query": "acme",
      "status": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/get_contact

Get contact

Read key

Everything about one contact: their fields, companies, owner, and their latest activities and open tasks.

Body

idnumberrequired

Contact id

curl -X POST "https://api.crossingedge.com/v1/actions/get_contact" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "id": 101
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_contact", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "id": 101
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_contact",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "id": 101
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/create_contact

Create contact

Read and write keyIdempotency-Key

Adds a contact. Needs a first name and an email or phone. Runs the workspace’s automations and duplicate check like a contact made in the app.

Body

firstNamestringrequired

First name

lastNamestring

Last name

emailstring

Email. A contact needs an email or a phone

phonestring

Phone, with country code

jobTitlestring

Job title

statusstring

Lifecycle status, one of the choices get_schema lists for contacts.status

sourcestring

Where they came from, one of the choices get_schema lists for contacts.source

linkedinstring

LinkedIn profile URL

telegramstring

Telegram username, like @priya

countrystring

Country they are based in, by name or two-letter code (India, IN)

statestring

Their state, province or region

citystring

Their city

ownerstring

Owner, by member email or name

companyIdsarray of number

Companies they work with, by id (replaces the current set)

companyNamestring

A company to link by exact name; made if the workspace has none by that name

customobject

Custom field values by field key (keys from get_schema)

curl -X POST "https://api.crossingedge.com/v1/actions/create_contact" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "firstName": "Priya"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/create_contact", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "firstName": "Priya"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/create_contact",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "firstName": "Priya"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/update_contact

Update contact

Read and write keyIdempotency-Key

Changes a contact. Only the fields passed change; companyName adds a company link, companyIds replaces the set.

Body

idnumberrequired

Contact id

firstNamestring

First name

lastNamestring

Last name

emailstring

Email. A contact needs an email or a phone

phonestring

Phone, with country code

jobTitlestring

Job title

statusstring

Lifecycle status, one of the choices get_schema lists for contacts.status

sourcestring

Where they came from, one of the choices get_schema lists for contacts.source

linkedinstring

LinkedIn profile URL

telegramstring

Telegram username, like @priya

countrystring

Country they are based in, by name or two-letter code (India, IN)

statestring

Their state, province or region

citystring

Their city

ownerstring

Owner, by member email or name

companyIdsarray of number

Companies they work with, by id (replaces the current set)

companyNamestring

A company to link by exact name; made if the workspace has none by that name

customobject

Custom field values by field key (keys from get_schema)

curl -X POST "https://api.crossingedge.com/v1/actions/update_contact" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "id": 101
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/update_contact", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "id": 101
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/update_contact",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "id": 101
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/delete_contact

Delete contact

Read and write keyPermanentIdempotency-Key

Deletes a contact for good, with their notes and history. Ask the person first, then call with confirm: true.

Body

idnumberrequired

Contact id

confirmbooleanrequired

True once the person has confirmed the delete

curl -X POST "https://api.crossingedge.com/v1/actions/delete_contact" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "id": 101,
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/delete_contact", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "id": 101,
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/delete_contact",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "id": 101,
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/list_tasks

List tasks

Read key

Tasks, open ones by default: yours, everyone’s you can see, or those on one record. Also lists other activity types with type.

Body

scopestring

Tasks you created or are on (default), or all you can see

One of mine all

statusstring

Default open

One of open done all

typestring

Default task

One of task call meeting email message note any

overdueboolean

Only those past due

dueBeforestring

Only those due before this ISO date

contactIdnumber

The contact it is about

companyIdnumber

The company it is about

dealIdnumber

The deal it is about

recordsarray of object

Other records it is about, as { object, id } (custom objects too)

limitnumber

Default 25, at most 100

curl -X POST "https://api.crossingedge.com/v1/actions/list_tasks" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "scope": "mine",
  "status": "open"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/list_tasks", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "scope": "mine",
    "status": "open"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/list_tasks",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "scope": "mine",
      "status": "open"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/get_task

Get task

Read key

One task (or any activity) with everything logged inside it: its calls, meetings, emails, messages, notes and sub-tasks.

Body

idstringrequired

Task id, like act_…

curl -X POST "https://api.crossingedge.com/v1/actions/get_task" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "id": "101"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_task", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "id": "101"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_task",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "id": "101"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/create_task

Create task

Read and write keyIdempotency-Key

Plans a task: what, when it is due, how urgent, who owns it (you by default), and the records it is about. Pass parentTaskId to make it a sub-task.

Body

subjectstringrequired

What needs doing

duestringrequired

Due date and time, ISO 8601, e.g. 2026-10-01T17:00:00+05:30

prioritystring

Default Medium

One of Low Medium High

assigneestring

Who owns it, by member email or name. Default: you

bodystring

Details

parentTaskIdstring

Make it a sub-task inside this task; it then takes that task’s records

notifyarray of string

People to keep informed, by member email or name

contactIdnumber

The contact it is about

companyIdnumber

The company it is about

dealIdnumber

The deal it is about

recordsarray of object

Other records it is about, as { object, id } (custom objects too)

curl -X POST "https://api.crossingedge.com/v1/actions/create_task" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "subject": "Call Priya about the renewal",
  "due": "2026-11-02T10:00:00Z"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/create_task", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "subject": "Call Priya about the renewal",
    "due": "2026-11-02T10:00:00Z"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/create_task",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "subject": "Call Priya about the renewal",
      "due": "2026-11-02T10:00:00Z"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/log_activity

Log activity

Read and write keyIdempotency-Key

Logs a call, meeting, email, message or note on records, or inside a task (taskId). Fields by type: call: direction (Incoming | Outgoing), outcome (Connected | No answer | Left voicemail | Wrong number | Busy); meeting: locationOrLink, agenda, outcome; email: direction (Incoming | Outgoing), subject; message: channel (SMS | WhatsApp | LinkedIn | Telegram), direction (Incoming | Outgoing); note: none. Required choices left out are filled with sensible defaults (calls and emails: Outgoing).

Body

typestringrequired

One of call meeting email message note

subjectstring

Short title

bodystring

What happened; required for a note

atstring

When, ISO 8601. Default now. A future time plans a meeting, call, email or message

durationMinutesnumber

How long, for calls and meetings

detailsobject

This type’s own fields (see the description)

taskIdstring

Log it inside this task; it then takes the task’s records

notifyarray of string

People to keep informed, by member email or name

privateboolean

Notes on a record only: visible to you alone

contactIdnumber

The contact it is about

companyIdnumber

The company it is about

dealIdnumber

The deal it is about

recordsarray of object

Other records it is about, as { object, id } (custom objects too)

curl -X POST "https://api.crossingedge.com/v1/actions/log_activity" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "type": "call"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/log_activity", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "type": "call"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/log_activity",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "type": "call"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/update_task

Update task

Read and write keyIdempotency-Key

Changes a task or activity. Only what is passed changes. status: planned | in_progress | done | cancelled.

Body

idstringrequired

Task or activity id

subjectstring

New subject

bodystring

New details

duestring

New due date, ISO 8601 (tasks), or when it happened (other types)

prioritystring

One of Low Medium High

statusstring

One of planned in_progress done cancelled

assigneestring

New owner, by member email or name

notifyarray of string

The full new list of people to keep informed, by email or name

detailsobject

Type fields to change

moveIntoTaskstring

Move it inside this task; it then takes that task’s records

moveOutOfTaskboolean

Take it out of the task it is in, keeping its records

contactIdnumber

The contact it is about. Passing any record replaces what it is linked to

companyIdnumber

The company it is about. Passing any record replaces what it is linked to

dealIdnumber

The deal it is about. Passing any record replaces what it is linked to

recordsarray of object

Other records it is about, as { object, id } (custom objects too). Passing any record replaces what it is linked to

curl -X POST "https://api.crossingedge.com/v1/actions/update_task" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "id": "101"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/update_task", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "id": "101"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/update_task",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "id": "101"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/update_note

Update note

Read and write keyIdempotency-Key

Changes a note on a record (ids like note_…, from get_contact). Only its author can.

Body

idstringrequired

Note id

bodystring

The new text

privateboolean

Visible to you alone

curl -X POST "https://api.crossingedge.com/v1/actions/update_note" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "id": "101"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/update_note", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "id": "101"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/update_note",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "id": "101"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/delete_note

Delete note

Read and write keyPermanentIdempotency-Key

Deletes a note on a record for good. Ask the person first, then call with confirm: true.

Body

idstringrequired

Note id

confirmbooleanrequired

True once the person has confirmed the delete

curl -X POST "https://api.crossingedge.com/v1/actions/delete_note" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "id": "101",
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/delete_note", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "id": "101",
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/delete_note",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "id": "101",
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/complete_task

Complete task

Read and write keyIdempotency-Key

Marks a task done.

Body

idstringrequired

Task id

curl -X POST "https://api.crossingedge.com/v1/actions/complete_task" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "id": "101"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/complete_task", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "id": "101"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/complete_task",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "id": "101"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/delete_task

Delete task

Read and write keyPermanentIdempotency-Key

Deletes a task or activity for good; a task takes everything logged inside it. Ask the person first, then call with confirm: true.

Body

idstringrequired

Task or activity id

confirmbooleanrequired

True once the person has confirmed the delete

curl -X POST "https://api.crossingedge.com/v1/actions/delete_task" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "id": "101",
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/delete_task", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "id": "101",
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/delete_task",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "id": "101",
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Records

Actions

Any record: companies, deals, contacts and the objects a workspace adds itself. Links between them, and deal splits.

POST/actions/search_records

Search records

Read key

Finds records of any object (companies, deals, contacts or a workspace object) by words in their name and fields, optionally narrowed by owner. Compact rows with ids; get_record has everything about one.

Body

objectstringrequired

contacts, companies, deals, or a workspace object by id, name or plural (get_schema lists them)

querystring

Words to match

ownerstring

Only records this member owns, by email or name

limitnumber

How many, default 20, at most 100

curl -X POST "https://api.crossingedge.com/v1/actions/search_records" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "object": "deals"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/search_records", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "object": "deals"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/search_records",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "object": "deals"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/get_record

Get record

Read key

Everything about one record of any object: its fields, what it is linked to (companies, people, deals, parents and subsidiaries, workspace relationships), and its latest activity and notes.

Body

objectstringrequired

contacts, companies, deals, or a workspace object by id, name or plural (get_schema lists them)

idnumberrequired

Record id

curl -X POST "https://api.crossingedge.com/v1/actions/get_record" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "object": "deals",
  "id": 101
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_record", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "object": "deals",
    "id": 101
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_record",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "object": "deals",
      "id": 101
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/create_record

Create record

Read and write keyIdempotency-Key

Adds a record of any object: a company, a deal (lands in the default pipeline unless pipeline or stage is given), a contact, or a workspace object. Runs automations and duplicate checks like the app.

Body

objectstringrequired

contacts, companies, deals, or a workspace object by id, name or plural (get_schema lists them)

fieldsobjectrequired

Field values. Companies: name, domain, industry, companySize, country, state, city, phone, linkedin, icp. Deals: name, amount, closeDate (YYYY-MM-DD), source, nextStep, lostReason, pipeline and stage (by name), companyIds, contactIds. Contacts: firstName, lastName, email, phone, jobTitle, status, source, linkedin, telegram, country, state, city, companyIds. Any object: owner (member email or name) and custom: { field label or id: value }. On a workspace object, pass its fields by label directly.

curl -X POST "https://api.crossingedge.com/v1/actions/create_record" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "deals",
  "fields": {}
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/create_record", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "deals",
    "fields": {}
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/create_record",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "deals",
      "fields": {}
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/update_record

Update record

Read and write keyIdempotency-Key

Changes a record of any object. Only the fields passed change; a deal moves stage by passing stage (and pipeline if it is in several). companyIds and contactIds replace the set; link_records adds or removes one.

Body

objectstringrequired

contacts, companies, deals, or a workspace object by id, name or plural (get_schema lists them)

idnumberrequired

Record id

fieldsobjectrequired

Field values. Companies: name, domain, industry, companySize, country, state, city, phone, linkedin, icp. Deals: name, amount, closeDate (YYYY-MM-DD), source, nextStep, lostReason, pipeline and stage (by name), companyIds, contactIds. Contacts: firstName, lastName, email, phone, jobTitle, status, source, linkedin, telegram, country, state, city, companyIds. Any object: owner (member email or name) and custom: { field label or id: value }. On a workspace object, pass its fields by label directly.

curl -X POST "https://api.crossingedge.com/v1/actions/update_record" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "deals",
  "id": 101,
  "fields": {}
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/update_record", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "deals",
    "id": 101,
    "fields": {}
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/update_record",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "deals",
      "id": 101,
      "fields": {}
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/set_deal_split

Set deal split

Read and write keyIdempotency-Key

Shares credit on a deal between its owner and other members. members replaces the whole split: each member (email or name) with a whole-number percent; the owner is never listed and holds the rest (at least 1%). Pass an empty list to end the split. Only works while the deal’s pipeline has split credit on. Everyone on a split can see and edit the deal, and reports by owner credit each their share.

Body

dealnumberrequired

Deal id

membersarray of objectrequired

Who shares credit besides the owner

curl -X POST "https://api.crossingedge.com/v1/actions/set_deal_split" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "deal": 101,
  "members": []
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/set_deal_split", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "deal": 101,
    "members": []
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/set_deal_split",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "deal": 101,
      "members": []
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/delete_record

Delete record

Read and write keyPermanentIdempotency-Key

Deletes a record of any object for good, with its notes and history. Ask the person first, then call with confirm: true.

Body

objectstringrequired

contacts, companies, deals, or a workspace object by id, name or plural (get_schema lists them)

idnumberrequired

Record id

confirmbooleanrequired

True once the person has confirmed the delete

curl -X POST "https://api.crossingedge.com/v1/actions/delete_record" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "deals",
  "id": 101,
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/delete_record", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "deals",
    "id": 101,
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/delete_record",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "deals",
      "id": 101,
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/link_records

Link records

Read and write keyIdempotency-Key

Links two records: a contact to a company, a contact or company to a deal (with an optional role), a parent company (from) to a subsidiary (to), or any two records a workspace relationship joins (pass relationship when several do).

Body

fromobjectrequired
toobjectrequired
rolestring

A contact’s or company’s role on a deal, e.g. Decision maker

relationshipstring

Which workspace relationship, by label or id, when several join the two

curl -X POST "https://api.crossingedge.com/v1/actions/link_records" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "from": {},
  "to": {}
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/link_records", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "from": {},
    "to": {}
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/link_records",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "from": {},
      "to": {}
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/unlink_records

Unlink records

Read and write keyIdempotency-Key

Removes a link between two records (the records themselves stay). Same pairs as link_records.

Body

fromobjectrequired
toobjectrequired
relationshipstring

Which workspace relationship, by label or id, when several join the two

curl -X POST "https://api.crossingedge.com/v1/actions/unlink_records" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "from": {},
  "to": {}
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/unlink_records", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "from": {},
    "to": {}
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/unlink_records",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "from": {},
      "to": {}
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Workspace settings

Actions

Pipelines, objects, fields, relationships, automations, members and workspace settings. Owners and admins.

POST/actions/get_settings

Get settings

Read key

How the workspace is set up: pipelines and their stages, objects, custom fields per object, the choices of standard fields (contact status, source, buying roles, company ICP), relationships, workspace settings (currency, fiscal year, business hours, stage time targets, file limits: maxFileMb and storageMb), automations, members and AI. Pass section to read just one.

Body

sectionstring

One of pipelines objects fields choices relationships workspace automations members ai

curl -X POST "https://api.crossingedge.com/v1/actions/get_settings" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "section": "pipelines"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_settings", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "section": "pipelines"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_settings",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "section": "pipelines"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/create_pipeline

Create pipeline

Read and write keyIdempotency-Key

Adds a deal pipeline with its stages. Needs at least one open stage; won and lost stages close a deal.

Body

namestringrequired

Pipeline name

descriptionstring

What it is for

stagesarray of objectrequired

The full list of stages, in order: { name, kind: open|won|lost, probability 0-100, color: gray|blue|green|yellow|orange|red|purple, targetHours (how long a deal should sit there) }. Keep a stage’s id (from get_settings) to rename it; a stage left out is removed (refused while open deals sit in it).

makeDefaultboolean

Make it the pipeline new deals land in

splitCreditboolean

Let several people share credit on its deals (see set_deal_split)

curl -X POST "https://api.crossingedge.com/v1/actions/create_pipeline" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Acme",
  "stages": []
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/create_pipeline", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "name": "Acme",
    "stages": []
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/create_pipeline",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "name": "Acme",
      "stages": []
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/update_pipeline

Update pipeline

Read and write keyIdempotency-Key

Renames a pipeline or changes its stages. stages replaces the whole list: keep each stage’s id to rename it; stages matched by name keep their deals.

Body

pipelinestringrequired

Pipeline name or id

namestring

New name

descriptionstring

New description

stagesarray of object

The full list of stages, in order: { name, kind: open|won|lost, probability 0-100, color: gray|blue|green|yellow|orange|red|purple, targetHours (how long a deal should sit there) }. Keep a stage’s id (from get_settings) to rename it; a stage left out is removed (refused while open deals sit in it).

splitCreditboolean

Let several people share credit on its deals. Off keeps existing splits; they stop counting until it is on again

curl -X POST "https://api.crossingedge.com/v1/actions/update_pipeline" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "pipeline": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/update_pipeline", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "pipeline": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/update_pipeline",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "pipeline": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/set_default_pipeline

Set default pipeline

Read and write keyIdempotency-Key

Makes a pipeline the one new deals land in.

Body

pipelinestringrequired

Pipeline name or id

curl -X POST "https://api.crossingedge.com/v1/actions/set_default_pipeline" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "pipeline": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/set_default_pipeline", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "pipeline": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/set_default_pipeline",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "pipeline": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/archive_pipeline

Archive pipeline

Read and write keyIdempotency-Key

Archives a pipeline (its deals and history stay; it can be restored) or restores one with archived: false. The last live pipeline can’t be archived.

Body

pipelinestringrequired

Pipeline name or id

archivedboolean

false to restore; default true

curl -X POST "https://api.crossingedge.com/v1/actions/archive_pipeline" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "pipeline": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/archive_pipeline", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "pipeline": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/archive_pipeline",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "pipeline": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/create_object

Create object

Read and write keyIdempotency-Key

Adds an object of the workspace’s own (like Projects or Tickets), with a required Name field to start. Add more fields with create_field, and join it to others with create_relationship.

Body

namestringrequired

Singular, e.g. Project

pluralstringrequired

Plural, e.g. Projects

iconstring

One of box folder ticket calendar chart tag star flag

colorstring

gray, blue, green, yellow, orange, red, purple

curl -X POST "https://api.crossingedge.com/v1/actions/create_object" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Acme",
  "plural": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/create_object", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "name": "Acme",
    "plural": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/create_object",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "name": "Acme",
      "plural": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/update_object

Update object

Read and write keyIdempotency-Key

Renames a workspace object or changes its icon, colour, or which fields name and describe its records.

Body

objectstringrequired

contacts, companies, deals, or a workspace object by id, name or plural

namestring

Singular

pluralstring

Plural

iconstring

One of box folder ticket calendar chart tag star flag

colorstring

gray, blue, green, yellow, orange, red, purple

titleFieldstring

Field (label or id) that names a record

subtitleFieldstring

Field (label or id) shown under the name

curl -X POST "https://api.crossingedge.com/v1/actions/update_object" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "deals"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/update_object", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "deals"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/update_object",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "deals"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/archive_object

Archive object

Read and write keyIdempotency-Key

Archives a workspace object (hidden, records kept, can be restored) or restores it with archived: false.

Body

objectstringrequired

contacts, companies, deals, or a workspace object by id, name or plural

archivedboolean

false to restore; default true

curl -X POST "https://api.crossingedge.com/v1/actions/archive_object" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "deals"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/archive_object", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "deals"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/archive_object",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "deals"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/delete_object

Delete object

Read and write keyPermanentIdempotency-Key

Deletes a workspace object for good, with its fields and views. Only allowed once it has no records, relationships or automations. Ask the person first, then call with confirm: true.

Body

objectstringrequired

contacts, companies, deals, or a workspace object by id, name or plural

confirmbooleanrequired

True once the person has confirmed

curl -X POST "https://api.crossingedge.com/v1/actions/delete_object" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "deals",
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/delete_object", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "deals",
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/delete_object",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "deals",
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/create_field

Create field

Read and write keyIdempotency-Key

Adds a custom field to any object, built in or the workspace’s own. Types: text, longText, number, currency, percent, date, datetime, checkbox, singleSelect, multiSelect, email, phone, url, country, user. Select types need options.

Body

objectstringrequired

contacts, companies, deals, or a workspace object by id, name or plural

labelstringrequired

Field name, e.g. Contract value

typestringrequired

One of text longText number currency percent date datetime checkbox singleSelect multiSelect email phone url country user

optionsarray of string

Choices, for singleSelect and multiSelect

helpstring

A line of help under the field

requiredboolean

Every record must have it

uniqueboolean

No two records may share a value (text, email, phone, url, number, currency, date)

defaultValueany

What new records start with

curl -X POST "https://api.crossingedge.com/v1/actions/create_field" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "deals",
  "label": "…",
  "type": "text"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/create_field", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "deals",
    "label": "…",
    "type": "text"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/create_field",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "deals",
      "label": "…",
      "type": "text"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/update_field

Update field

Read and write keyIdempotency-Key

Changes a custom field’s label, help, required, unique or default. Its type can’t change. To rename or remove choices use set_field_choices; adding choices works here too.

Body

objectstringrequired

contacts, companies, deals, or a workspace object by id, name or plural

fieldstringrequired

Field label or id

labelstring

New label

helpstring

Help line

requiredboolean

Required

uniqueboolean

Unique

defaultValueany

Default for new records

optionsarray of string

Full list of choices (only adding; use set_field_choices to rename or remove)

curl -X POST "https://api.crossingedge.com/v1/actions/update_field" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "deals",
  "field": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/update_field", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "deals",
    "field": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/update_field",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "deals",
      "field": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/set_field_choices

Set field choices

Read and write keyIdempotency-Key

Sets the choices of a select field: a custom single or multi select, or a standard one (contacts: status, source, buyingRoles; companies: icp). Records using a removed or renamed choice move through replacements: { old: new } (null clears them). Standard fields also take colours and a default.

Body

objectstringrequired

contacts, companies, deals, or a workspace object by id, name or plural

fieldstringrequired

Field label or id, or status / source / buyingRoles / icp

choicesarray of objectrequired

The full list, in order: strings, or { value, color (gray, blue, green, yellow, orange, red, purple) }

replacementsobject

Where records on an old choice go: { "Old": "New" or null }

defaultValuestring

Standard fields: the choice new records start with

curl -X POST "https://api.crossingedge.com/v1/actions/set_field_choices" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "deals",
  "field": "…",
  "choices": []
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/set_field_choices", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "deals",
    "field": "…",
    "choices": []
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/set_field_choices",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "deals",
      "field": "…",
      "choices": []
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/archive_field

Archive field

Read and write keyIdempotency-Key

Archives a custom field (hidden, values kept, can be restored) or restores it with archived: false. A field automations use needs force: true, which leaves those automations flagged.

Body

objectstringrequired

contacts, companies, deals, or a workspace object by id, name or plural

fieldstringrequired

Field label or id

archivedboolean

false to restore; default true

forceboolean

Archive even though automations use it

curl -X POST "https://api.crossingedge.com/v1/actions/archive_field" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "deals",
  "field": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/archive_field", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "deals",
    "field": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/archive_field",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "deals",
      "field": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/arrange_fields

Arrange fields

Read and write keyIdempotency-Key

Shapes an object’s fields for everyone in the workspace: the order they appear in (record pages, forms, tables), standard fields to hide or show again, and standard fields to make required or optional. Fields are named by label or key. order may list just the fields that should come first; the rest keep their order after them. Hidden fields keep their data. Name, owner, stage, email and phone can’t be hidden; Crossing Edge’s own fields (created at and so on) can’t be required. Required is checked when people save (app, Claude, the assistant), not on leads captured automatically. Custom fields are required on the field itself (update_field) and archived rather than hidden.

Body

objectstringrequired

contacts, companies, deals, or a workspace object by id, name or plural

orderarray of string

Fields in the order they should appear, first first

hidearray of string

Standard fields to hide

showarray of string

Hidden standard fields to show again

requirearray of string

Standard fields to make required

optionalarray of string

Standard fields to make optional again

curl -X POST "https://api.crossingedge.com/v1/actions/arrange_fields" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "deals"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/arrange_fields", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "deals"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/arrange_fields",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "deals"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/delete_field

Delete field

Read and write keyPermanentIdempotency-Key

Deletes an archived custom field and every value it holds, permanently. It cannot be undone, so always ask the person first and only then call with confirm: true. Without confirm it reports what would be erased (records holding a value) and anything still using the field (automations, reports, calculated fields, stage timing), which must be changed first. Archive the field with archive_field before deleting it. Standard fields are never deleted: hide them with arrange_fields.

Body

objectstringrequired

contacts, companies, deals, or a workspace object by id, name or plural

fieldstringrequired

Custom field label or id

confirmboolean

true only after the person has agreed to erase it for good

curl -X POST "https://api.crossingedge.com/v1/actions/delete_field" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "deals",
  "field": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/delete_field", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "deals",
    "field": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/delete_field",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "deals",
      "field": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/create_relationship

Create relationship

Read and write keyIdempotency-Key

Joins two objects so their records can be linked, e.g. companies ↔ Projects. Each side gets its own label: what the other side is called when read from it.

Body

fromstringrequired

contacts, companies, deals, or a workspace object by id, name or plural

tostringrequired

contacts, companies, deals, or a workspace object by id, name or plural

fromLabelstringrequired

What a from record calls its linked to records, e.g. Projects

toLabelstringrequired

What a to record calls its linked from records, e.g. Account

manyToboolean

A from record may hold several to records (default true)

manyFromboolean

A to record may be held by several from records (default true)

curl -X POST "https://api.crossingedge.com/v1/actions/create_relationship" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "from": "…",
  "to": "…",
  "fromLabel": "…",
  "toLabel": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/create_relationship", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "from": "…",
    "to": "…",
    "fromLabel": "…",
    "toLabel": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/create_relationship",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "from": "…",
      "to": "…",
      "fromLabel": "…",
      "toLabel": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/update_relationship

Update relationship

Read and write keyIdempotency-Key

Renames a relationship’s labels or changes whether each side may hold several records.

Body

relationshipstringrequired

Relationship id or either label

fromLabelstring

New from label

toLabelstring

New to label

manyToboolean

manyTo

manyFromboolean

manyFrom

showReverseboolean

Show it on the to side too

curl -X POST "https://api.crossingedge.com/v1/actions/update_relationship" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "relationship": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/update_relationship", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "relationship": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/update_relationship",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "relationship": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/archive_relationship

Archive relationship

Read and write keyIdempotency-Key

Archives a relationship (hidden, links kept, can be restored) or restores it with archived: false.

Body

relationshipstringrequired

Relationship id or either label

archivedboolean

false to restore; default true

curl -X POST "https://api.crossingedge.com/v1/actions/archive_relationship" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "relationship": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/archive_relationship", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "relationship": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/archive_relationship",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "relationship": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/delete_relationship

Delete relationship

Read and write keyPermanentIdempotency-Key

Deletes a relationship for good. Only allowed once no records are linked through it. Ask the person first, then call with confirm: true.

Body

relationshipstringrequired

Relationship id or either label

confirmbooleanrequired

True once the person has confirmed

curl -X POST "https://api.crossingedge.com/v1/actions/delete_relationship" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "relationship": "…",
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/delete_relationship", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "relationship": "…",
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/delete_relationship",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "relationship": "…",
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/update_workspace_settings

Update workspace settings

Read and write keyIdempotency-Key

Changes workspace-wide settings: its name, currency (USD, EUR, GBP, INR, …), fiscal year start month, business hours for stage clocks, stage time targets for contact statuses ({ "contacts.status.Working": 48 } hours; 0 removes), which statuses make the funnel, which select field a record’s stage clock follows, and the file limits: the largest file anyone may upload (maxFileMb, 1 to 25 MB, default 5) and all the workspace’s files together (storageMb, 100 to 5120 MB, default 1024). Lowering a file limit keeps files already stored; only new uploads are checked.

Body

namestring

Workspace name

currencystring

ISO currency code

fiscalYearStartnumber

Month the fiscal year starts, 1-12

businessHoursobject

{ mode: 'calendar' | 'business', days: [1..5] (0 is Sunday), startMinute: 540, endMinute: 1080, timezone: 'Asia/Kolkata' }

targetsobject

Hours allowed per stage, keyed object.field.value

funnelarray of string

Contact statuses in funnel order

tracksobject

Which select field each object’s stage clock follows, e.g. { contacts: "status" }

maxFileMbnumber

The largest file anyone may upload, in MB: 1 to 25

storageMbnumber

All the workspace’s files together, in MB: 100 to 5120 (5 GB)

curl -X POST "https://api.crossingedge.com/v1/actions/update_workspace_settings" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Acme",
  "currency": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/update_workspace_settings", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "name": "Acme",
    "currency": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/update_workspace_settings",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "name": "Acme",
      "currency": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/create_automation

Create automation

Read and write keyIdempotency-Key

Adds an automation: a rule that acts when records are created or change. An automation: { name, object (contacts, companies, deals, a workspace object, or activities), enabled, triggers: [{ kind: 'created' } | { kind: 'changed', field, to? } | { kind: 'overdue', days } (activities only)], conditions: [{ key, values? | text? | min?, max? }], tree: [node] }. Activities (object 'activities') are tasks, calls, meetings, emails, messages and notes: filter by type (task, call, meeting, email, message, note) and status (planned, in_progress, done, cancelled); other fields: subject, body, at (due date), overdueDays, ownerId (the assignee), createdBy, completedAt, linkedTo (contacts, companies, deals), contactOwnerId, companyOwnerId, dealOwnerId, dealStage. { kind: 'overdue', days: 2 } runs once per activity still to do, 2 whole days past its due date (checked every 15 minutes). On an activity: owner reassigns it (who: owner = current assignee, creator, a user, or { kind: 'field', field: 'dealOwnerId' } for the linked deal's owner); set changes status, subject, body or at (at may be a when, e.g. { kind: 'in', amount: 2, unit: 'days' }); activity and note steps land on the records the activity is on; related { from: contacts | companies | deals } reaches those records; link is not available. A node is { id, kind, config, children: [] }; kinds and their config: - condition { filters: [{ key, values? }] } (children run only when it matches) - activity { type: task|call|meeting|email|message|note, subject (body for a note), who?: { kind: owner|creator } | { kind: 'user', userId }, when?: { kind: 'in', amount, unit: hours|days|weeks, skipWeekends? } } - note { body } - set { field, value } - owner { who }: who is { kind: 'owner' } | { kind: 'creator' } | { kind: 'user', userId } | { kind: 'field', field } (a user field on the record) | { kind: 'rotate', id, userIds: [...] } (take turns, fair over time, skipping anyone who left; id is any short unique name like 'rot_inbound', and keeping it keeps the place in the turn) | { kind: 'rules', rules: [{ when: [{ key, values }], then: who }], otherwise: who } (first match wins; inside rules { kind: 'user', userId: 0 } means nobody, so the record stays unassigned). This is how leads get assigned: webhook leads arrive unassigned and their source is the webhook's name. - record { object, title (may use {{field}}), values?, pipelineId?, stageId? }: object is a standard object or a workspace object's id (obj_…, from get_schema); title becomes the new record's name. values must set every field that object marks required and has no default, or the rule is refused. The new record is attached to the one that started the rule (contacts, companies and deals directly; other objects through a relationship between the two). - related { from, relationshipId?, direction? } (its children act on the related record) - link { from, recordId, relationshipId?, mode?: 'unlink' } Lead assignment example: { name: 'Assign inbound leads', object: 'contacts', triggers: [{ kind: 'created' }], conditions: [{ key: 'source', values: ['Website form'] }], tree: [{ id: 'n1', kind: 'owner', config: { who: { kind: 'rules', rules: [{ when: [{ key: 'city', values: ['Chennai'] }], then: { kind: 'user', userId: 12 } }], otherwise: { kind: 'rotate', id: 'rot_inbound', userIds: [12, 15] } } }, children: [] }] }. Example: { name: 'Call new leads', object: 'contacts', triggers: [{ kind: 'created' }], conditions: [], tree: [{ id: 'n1', kind: 'activity', config: { type: 'task', subject: 'Call {{firstName}}', who: { kind: 'owner' }, when: { kind: 'in', amount: 1, unit: 'days' } }, children: [] }] }. Try it with test_automation before switching it on.

Body

automationobjectrequired

The automation, as described above

curl -X POST "https://api.crossingedge.com/v1/actions/create_automation" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "automation": {}
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/create_automation", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "automation": {}
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/create_automation",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "automation": {}
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/update_automation

Update automation

Read and write keyIdempotency-Key

Changes an automation: pass only what changes (name, enabled, triggers, conditions, tree). enabled: false switches it off without deleting it.

Body

automationstringrequired

Automation name or id

changesobjectrequired

Fields to change, same shape as create_automation

curl -X POST "https://api.crossingedge.com/v1/actions/update_automation" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "automation": "…",
  "changes": {}
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/update_automation", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "automation": "…",
    "changes": {}
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/update_automation",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "automation": "…",
      "changes": {}
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/test_automation

Test automation

Read key

Dry-runs an automation over existing records: which would match, why, and what it would do. Changes nothing.

Body

automationstringrequired

Automation name or id

limitnumber

How many records to try, default 20, at most 50

curl -X POST "https://api.crossingedge.com/v1/actions/test_automation" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "automation": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/test_automation", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "automation": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/test_automation",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "automation": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/delete_automation

Delete automation

Read and write keyPermanentIdempotency-Key

Deletes an automation and its run history for good (update_automation with enabled: false just switches it off). Ask the person first, then call with confirm: true.

Body

automationstringrequired

Automation name or id

confirmbooleanrequired

True once the person has confirmed

curl -X POST "https://api.crossingedge.com/v1/actions/delete_automation" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "automation": "…",
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/delete_automation", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "automation": "…",
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/delete_automation",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "automation": "…",
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/add_member

Add member

Read and write keyIdempotency-Key

Invites someone to the workspace by email (or phone): they are added straight away and emailed an invite with a Join button (notify: false to add them quietly). Role: member (default) or admin; permissions: a preset (full, standard, own, readOnly) or leave it to the workspace default. The answer says whether the invite went out.

Body

emailstringrequired

Their email or phone

namestring

Their name

rolestring

One of member admin

permissionsstring

Preset: full, standard, own or readOnly

notifyboolean

Email them an invite (default true)

curl -X POST "https://api.crossingedge.com/v1/actions/add_member" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "email": "priya@acme.com"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/add_member", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "email": "priya@acme.com"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/add_member",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "email": "priya@acme.com"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/resend_invite

Resend invite

Read and write keyIdempotency-Key

Emails someone who was added but hasn’t signed in yet their invite again.

Body

memberstringrequired

Member email or name

curl -X POST "https://api.crossingedge.com/v1/actions/resend_invite" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "member": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/resend_invite", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "member": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/resend_invite",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "member": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/update_member

Update member

Read and write keyIdempotency-Key

Changes a member’s role (member or admin) or what they can do: a preset (full, standard, own, readOnly), "default" for the workspace default, or a full permissions object.

Body

memberstringrequired

Member email or name

rolestring

One of member admin

permissionsany

Preset name, "default", or a permissions object

curl -X POST "https://api.crossingedge.com/v1/actions/update_member" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "member": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/update_member", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "member": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/update_member",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "member": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/remove_member

Remove member

Read and write keyPermanentIdempotency-Key

Removes someone from the workspace; the records they own stay. Ask the person first, then call with confirm: true.

Body

memberstringrequired

Member email or name

confirmbooleanrequired

True once the person has confirmed

curl -X POST "https://api.crossingedge.com/v1/actions/remove_member" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "member": "…",
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/remove_member", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "member": "…",
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/remove_member",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "member": "…",
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/update_ai_settings

Update AI settings

Read and write keyIdempotency-Key

Switches AI duplicate detection on or off. Switching on can also check existing contacts and companies from a date (YYYY-MM-DD) or all of them.

Body

duplicatesbooleanrequired

Detect duplicates

backfillSincestring

'all' or YYYY-MM-DD: check existing records too

curl -X POST "https://api.crossingedge.com/v1/actions/update_ai_settings" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "duplicates": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/update_ai_settings", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "duplicates": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/update_ai_settings",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "duplicates": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Insights and history

Actions

Duplicates, merging, history, stage times, overdue work, insights, spend and saved views.

POST/actions/find_duplicates

Find duplicates

Read and write keyIdempotency-Key

Finds duplicate contacts or companies. With an id: checks that record now (AI, when the workspace has it on) and lists its lookalikes. Without one: every open AI suggestion plus exact lookalikes (same name, email, phone or website) across the workspace, most likely first. Follow with merge_preview and merge_records, or dismiss_duplicate.

Body

objectstringrequired

contacts or companies

One of contacts companies

idnumber

One record to check

limitnumber

How many pairs, default 30, at most 200

curl -X POST "https://api.crossingedge.com/v1/actions/find_duplicates" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "contacts"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/find_duplicates", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "contacts"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/find_duplicates",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "contacts"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/scan_duplicates

Scan for duplicates

Read and write keyIdempotency-Key

Runs the AI duplicate check over existing contacts and companies (all of them, or those created since a date), in the background. Switches AI duplicate detection on for the workspace. Owners and admins. Pairs already judged are skipped, so re-running is cheap; call find_duplicates afterwards.

Body

sincestring

'all' (default) or YYYY-MM-DD

curl -X POST "https://api.crossingedge.com/v1/actions/scan_duplicates" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "since": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/scan_duplicates", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "since": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/scan_duplicates",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "since": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/dismiss_duplicate

Dismiss duplicate

Read and write keyIdempotency-Key

Marks two records as not duplicates, so the pair stops being suggested.

Body

objectstringrequired

contacts or companies

One of contacts companies

anumberrequired

One record id

bnumberrequired

The other record id

curl -X POST "https://api.crossingedge.com/v1/actions/dismiss_duplicate" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "contacts",
  "a": 101,
  "b": 101
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/dismiss_duplicate", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "contacts",
    "a": 101,
    "b": 101
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/dismiss_duplicate",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "contacts",
      "a": 101,
      "b": 101
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/merge_preview

Merge preview

Read key

Shows what merging two contacts or companies would do before doing it: which values the kept record keeps or takes from the duplicate (with the choices per field), and the deals, activities, notes, links and history that move over. Show this to the person before merge_records.

Body

objectstringrequired

contacts or companies

One of contacts companies

keepnumberrequired

Id of the record that stays

removenumberrequired

Id of the duplicate folded into it and then deleted

curl -X POST "https://api.crossingedge.com/v1/actions/merge_preview" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "object": "contacts",
  "keep": 101,
  "remove": 101
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/merge_preview", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "object": "contacts",
    "keep": 101,
    "remove": 101
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/merge_preview",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "object": "contacts",
      "keep": 101,
      "remove": 101
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/merge_records

Merge records

Read and write keyPermanentIdempotency-Key

Merges a duplicate contact or company into the one that stays: its deals, activities, notes, links, people and history move over, chosen field values are copied, and the duplicate is deleted. Defaults match the app (the kept value wins, blanks are filled, companies are kept from both). Override per field with choices: { field: existing | incoming | both }. Can’t be undone: show merge_preview, ask the person, then call with confirm: true.

Body

objectstringrequired

contacts or companies

One of contacts companies

keepnumberrequired

Id of the record that stays

removenumberrequired

Id of the duplicate

choicesobject

Per field, from merge_preview: "existing" keeps the kept record’s value, "incoming" takes the duplicate’s, "both" keeps both companies

confirmbooleanrequired

True once the person has confirmed

curl -X POST "https://api.crossingedge.com/v1/actions/merge_records" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "contacts",
  "keep": 101,
  "remove": 101,
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/merge_records", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "contacts",
    "keep": 101,
    "remove": 101,
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/merge_records",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "contacts",
      "keep": 101,
      "remove": 101,
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/get_history

Get history

Read key

A record’s change history, newest first: who created, changed (field by field, from and to), linked, merged or deleted things, and when. Any object. Page with before.

Body

objectstringrequired

Any object

idnumberrequired

Record id

limitnumber

How many, default 20, at most 100

beforestring

The cursor from the previous page

curl -X POST "https://api.crossingedge.com/v1/actions/get_history" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "object": "deals",
  "id": 101
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_history", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "object": "deals",
    "id": 101
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_history",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "object": "deals",
      "id": 101
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/get_stage_times

Get stage times

Read key

How long a record has spent in each stage (deal pipeline stages, or a contact’s status), counting business hours when the workspace uses them: where it is now, for how long, against the target, and every stage it passed through.

Body

objectstringrequired

Any object with a stage: deals, contacts, …

idnumberrequired

Record id

curl -X POST "https://api.crossingedge.com/v1/actions/get_stage_times" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "object": "deals",
  "id": 101
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_stage_times", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "object": "deals",
    "id": 101
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_stage_times",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "object": "deals",
      "id": 101
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/list_overdue

List overdue

Read key

Records that have sat in their stage past its target (overdue) or are close to it (due soon), longest over first. Only records you can see.

Body

objectstring

Only this object (deals, contacts, …)

includestring

Default overdue

One of overdue dueSoon both

limitnumber

How many, default 30

curl -X POST "https://api.crossingedge.com/v1/actions/list_overdue" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "object": "deals",
  "include": "overdue"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/list_overdue", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "object": "deals",
    "include": "overdue"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/list_overdue",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "object": "deals",
      "include": "overdue"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/get_insights

Get insights

Read key

The Insights page as data: leads and conversion, won value, win rate, time to win, the funnel, segments, execution, what needs attention, and observations, for a period against the one before. Owners and admins.

Body

periodstring

Default month

One of week month quarter year custom

yearnumber

Year

quarternumber

1-4

fromstring

custom: first day, YYYY-MM-DD

tostring

custom: last day, YYYY-MM-DD

pipelinestring

Pipeline name or id

filtersarray of object

Deal filters: [{ key, values? | text? | min?, max? }]

curl -X POST "https://api.crossingedge.com/v1/actions/get_insights" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "period": "week",
  "year": 101
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_insights", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "period": "week",
    "year": 101
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_insights",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "period": "week",
      "year": 101
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/get_spend

Get spend

Read key

Marketing spend by source and month, as entered for Insights. Owners and admins.

curl -X POST "https://api.crossingedge.com/v1/actions/get_spend" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_spend", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_spend",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/set_spend

Set spend

Read and write keyIdempotency-Key

Records what was spent on a lead source in a month (amount 0 means nothing was spent; null clears it back to unknown). Owners and admins.

Body

sourcestringrequired

Lead source, as in contact sources

monthstringrequired

YYYY-MM

amountnumberrequired

Amount in the workspace currency, or null for unknown

curl -X POST "https://api.crossingedge.com/v1/actions/set_spend" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "source": "…",
  "month": "…",
  "amount": 12000
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/set_spend", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "source": "…",
    "month": "…",
    "amount": 12000
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/set_spend",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "source": "…",
      "month": "…",
      "amount": 12000
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/get_automation_runs

Get automation runs

Read key

What automations actually did, newest first: which record, whether it matched, what it did, and any error. One automation or all.

Body

automationstring

Automation name or id; all when left out

failedOnlyboolean

Only runs with an error

limitnumber

How many, default 30, at most 200

curl -X POST "https://api.crossingedge.com/v1/actions/get_automation_runs" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "automation": "…",
  "failedOnly": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_automation_runs", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "automation": "…",
    "failedOnly": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_automation_runs",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "automation": "…",
      "failedOnly": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/list_views

List views

Read key

Saved list views: yours and the shared ones, with their filters, sort and hidden columns, and which one opens by default for you.

Body

objectstring

Only views of this object

curl -X POST "https://api.crossingedge.com/v1/actions/list_views" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "object": "deals"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/list_views", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "object": "deals"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/list_views",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "object": "deals"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/save_view

Save view

Read and write keyIdempotency-Key

Saves a list view, or changes one (pass view). filters: [{ key, values? | text? | min?, max? }] with field keys from get_schema; sort: { id: field key, dir: asc | desc }; hidden: column keys to hide; cardFields: what each card shows on the board, as field keys in order (at most 5; timeInStage = time in the current stage; a field of a linked record as <relation field>.<field>, e.g. companyIds.industry on deals; [] for just the name); shared: everyone sees it (needs the share-views permission).

Body

objectstringrequired

Object the view lists

viewstring

An existing view’s name or id, to change it

namestring

View name

filtersarray of object
sortobject

{ id, dir }

hiddenarray of string
cardFieldsarray of string

Field keys shown on board cards, in order, at most 5; companyIds.industry reads the linked company

sharedboolean

Share with the workspace

makeDefaultboolean

Open this view by default for you

curl -X POST "https://api.crossingedge.com/v1/actions/save_view" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "deals"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/save_view", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "deals"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/save_view",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "deals"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/set_default_view

Set default view

Read and write keyIdempotency-Key

Which view a list opens on for you: a saved view by name or id, a built-in one (all, mine, leads, open), or null for the page default.

Body

objectstringrequired

Object

viewstringrequired

View name or id, a built-in id, or null

curl -X POST "https://api.crossingedge.com/v1/actions/set_default_view" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "object": "deals",
  "view": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/set_default_view", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "object": "deals",
    "view": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/set_default_view",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "object": "deals",
      "view": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/delete_view

Delete view

Read and write keyPermanentIdempotency-Key

Deletes a saved view (the records it lists are untouched). A shared view disappears for everyone.

Body

viewstringrequired

View name or id

objectstring

Its object, when names repeat across objects

curl -X POST "https://api.crossingedge.com/v1/actions/delete_view" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "view": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/delete_view", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "view": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/delete_view",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "view": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/delete_report

Delete report

Read and write keyPermanentIdempotency-Key

Deletes a report for good (its author, or an owner or admin). Ask the person first, then call with confirm: true.

Body

reportstringrequired

Report id or name

confirmbooleanrequired

True once the person has confirmed

curl -X POST "https://api.crossingedge.com/v1/actions/delete_report" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "report": "…",
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/delete_report", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "report": "…",
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/delete_report",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "report": "…",
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Email

Actions

Email conversations, replies, drafts in the member’s own style, and their writing profile.

POST/actions/list_email_conversations

List email conversations

Read key

Email conversations brought in by Gmail sync or logged by hand: subject, people, how many emails, the newest one, its AI brief and whether it needs a reply. The workspace’s (as far as the person can see), only their own inboxes with mine: true, or one record’s.

Body

mineboolean

Only conversations from the person’s own inboxes

qstring

Search subject, people and text

recordobject

Only the ones on this record

curl -X POST "https://api.crossingedge.com/v1/actions/list_email_conversations" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "mine": true,
  "q": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/list_email_conversations", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "mine": true,
    "q": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/list_email_conversations",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "mine": True,
      "q": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/read_email_conversation

Read email conversation

Read key

One email conversation, oldest first: each email’s sender, recipients and own text (quoted history cut), the brief, the records it is on, and whether the person can reply from Crossing Edge (from which of their inboxes, and who Reply and Reply all go to).

Body

keystringrequired

Conversation key from list_email_conversations

curl -X POST "https://api.crossingedge.com/v1/actions/read_email_conversation" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "key": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/read_email_conversation", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "key": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/read_email_conversation",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "key": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/draft_email_reply

Draft email reply

Read key

Drafts the person’s reply to an email conversation in their own writing style (learned from the email they send), with their signature on the end. Nothing is sent: show them the draft, let them change it, then send_email_reply. Facts the thread does not give are left as [placeholders] to fill in.

Body

keystringrequired

Conversation key

allboolean

Reply all rather than reply

curl -X POST "https://api.crossingedge.com/v1/actions/draft_email_reply" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "key": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/draft_email_reply", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "key": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/draft_email_reply",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "key": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/send_email_reply

Send email reply

Read and write keyIdempotency-Key

Sends a reply to an email conversation through the person’s own Gmail, threaded under it, and keeps it in the conversation. Recipients default to Reply (or Reply all with all: true); to, cc and bcc replace them. It goes to people outside the workspace: show the person the text and recipients, then call with confirm: true. Attachments are added in the app.

Body

keystringrequired

Conversation key

textstringrequired

The message, plain text

allboolean

Reply all: everyone else on the thread too

toarray of string

Email addresses to send to (replaces the default)

ccarray of string

Cc addresses (replaces the default)

bccarray of string

Bcc addresses

subjectstring

Subject (default Re: the conversation’s)

inboxstring

Which of the person’s inboxes to send from (default the one it came through)

confirmbooleanrequired

True once the person has seen it and said send

curl -X POST "https://api.crossingedge.com/v1/actions/send_email_reply" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "key": "…",
  "text": "…",
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/send_email_reply", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "key": "…",
    "text": "…",
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/send_email_reply",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "key": "…",
      "text": "…",
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/get_writing_profile

Get writing profile

Read key

How the person writes their email, as Crossing Edge learned it from what they send (tone, length, greeting, sign-off, phrases, what they avoid), and the emails they pasted in to learn from. Private to them.

curl -X POST "https://api.crossingedge.com/v1/actions/get_writing_profile" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_writing_profile", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_writing_profile",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/relearn_writing_profile

Learn writing style again

Read and write keyIdempotency-Key

Learns the person’s writing profile again now, from their latest sent email and pasted samples.

curl -X POST "https://api.crossingedge.com/v1/actions/relearn_writing_profile" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'
const res = await fetch("https://api.crossingedge.com/v1/actions/relearn_writing_profile", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({}),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/relearn_writing_profile",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/add_writing_sample

Add writing sample

Read and write keyIdempotency-Key

Teaches the person’s writing profile from an email they wrote, pasted whole (up to 5 kept). Use their own email only, as they sent it.

Body

textstringrequired

An email the person wrote, whole

curl -X POST "https://api.crossingedge.com/v1/actions/add_writing_sample" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "text": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/add_writing_sample", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "text": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/add_writing_sample",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "text": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/set_email_signature

Set email signature

Read and write keyIdempotency-Key

The signature added to the end of the person’s drafted replies: text to use word for word (line breaks kept; "" for no signature), or null to go back to the one found at the end of their emails.

Body

textstringrequired

The signature, or "" for none, or null for the one in their email

curl -X POST "https://api.crossingedge.com/v1/actions/set_email_signature" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "text": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/set_email_signature", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "text": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/set_email_signature",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "text": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/remove_writing_sample

Remove writing sample

Read and write keyPermanentIdempotency-Key

Removes one of the emails the person pasted into their writing profile, by its index from get_writing_profile.

Body

indexnumberrequired

Index from get_writing_profile

curl -X POST "https://api.crossingedge.com/v1/actions/remove_writing_sample" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "index": 101
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/remove_writing_sample", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "index": 101
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/remove_writing_sample",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "index": 101
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/forget_writing_profile

Forget writing profile

Read and write keyPermanentIdempotency-Key

Forgets what was learned about how the person writes, and the emails they pasted. It learns again from the next emails they send. Ask the person first, then call with confirm: true.

Body

confirmbooleanrequired

True once the person has confirmed

curl -X POST "https://api.crossingedge.com/v1/actions/forget_writing_profile" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/forget_writing_profile", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/forget_writing_profile",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Gmail sync

Actions

The member’s own connected Gmail inboxes and their Review.

POST/actions/get_gmail

Get Gmail

Read key

The person’s own connected Gmail inboxes: address, status, last check, problems, how much was brought in, and how many emails wait in each Review. Connecting an inbox needs a Gmail app password, typed in Settings › Email, never in a chat.

curl -X POST "https://api.crossingedge.com/v1/actions/get_gmail" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_gmail", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_gmail",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/list_gmail_brought_in

List emails brought in

Read key

Emails Gmail sync brought into the CRM from one of the person’s inboxes: when, which way, why, and the records each was logged on.

Body

inboxstring

Inbox address or id (optional when there is one)

daysnumber

How many days back (default 7)

curl -X POST "https://api.crossingedge.com/v1/actions/list_gmail_brought_in" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "inbox": "…",
  "days": 101
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/list_gmail_brought_in", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "inbox": "…",
    "days": 101
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/list_gmail_brought_in",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "inbox": "…",
      "days": 101
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/set_gmail_status

Pause or resume Gmail

Read and write keyIdempotency-Key

Pauses or resumes Gmail sync for one of the person’s inboxes.

Body

inboxstring

Inbox address or id (optional when there is one)

statusstringrequired

One of paused active

curl -X POST "https://api.crossingedge.com/v1/actions/set_gmail_status" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "status": "paused"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/set_gmail_status", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "status": "paused"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/set_gmail_status",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "status": "paused"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/check_gmail_now

Check Gmail now

Read and write keyIdempotency-Key

Reads new mail in one of the person’s inboxes now, rather than waiting for the next minute.

Body

inboxstring

Inbox address or id (optional when there is one)

curl -X POST "https://api.crossingedge.com/v1/actions/check_gmail_now" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "inbox": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/check_gmail_now", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "inbox": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/check_gmail_now",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "inbox": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/disconnect_gmail

Disconnect Gmail

Read and write keyPermanentIdempotency-Key

Disconnects one of the person’s own inboxes; emails already brought in stay. Ask the person first, then call with confirm: true.

Body

inboxstring

Inbox address or id (optional when there is one)

confirmbooleanrequired

True once the person has confirmed

curl -X POST "https://api.crossingedge.com/v1/actions/disconnect_gmail" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/disconnect_gmail", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/disconnect_gmail",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/list_team_inboxes

List team inboxes

Read key

Owners and admins: every member’s connected Gmail inbox (address, status, last check). Never their mail.

curl -X POST "https://api.crossingedge.com/v1/actions/list_team_inboxes" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const res = await fetch("https://api.crossingedge.com/v1/actions/list_team_inboxes", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/list_team_inboxes",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/disconnect_team_inbox

Disconnect a member’s inbox

Read and write keyPermanentIdempotency-Key

Owners and admins: disconnects a member’s Gmail inbox, by its id from list_team_inboxes. Ask the person first, then call with confirm: true.

Body

idstringrequired

Inbox id

confirmbooleanrequired

True once the person has confirmed

curl -X POST "https://api.crossingedge.com/v1/actions/disconnect_team_inbox" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "id": "101",
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/disconnect_team_inbox", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "id": "101",
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/disconnect_team_inbox",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "id": "101",
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/list_email_review

List emails to review

Read key

Emails waiting in the person’s own Review page (the ones Jev was unsure about: maybe not sales, maybe private, many people): who, subject, snippet and why. Only ever their own inbox.

Body

inboxstring

Inbox address or id (optional: all of theirs)

curl -X POST "https://api.crossingedge.com/v1/actions/list_email_review" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "inbox": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/list_email_review", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "inbox": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/list_email_review",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "inbox": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/read_review_email

Read email to review

Read key

One email waiting in the person’s Review, in full, by its id from list_email_review.

Body

idstringrequired

Email id

curl -X POST "https://api.crossingedge.com/v1/actions/read_review_email" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "id": "101"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/read_review_email", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "id": "101"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/read_review_email",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "id": "101"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/bring_in_review_emails

Bring emails into the CRM

Read and write keyIdempotency-Key

Brings emails from the person’s Review into the CRM: logged on the people (and their companies) outside the team, creating contacts where needed. By id from list_email_review.

Body

idsarray of stringrequired

Email ids

curl -X POST "https://api.crossingedge.com/v1/actions/bring_in_review_emails" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "ids": []
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/bring_in_review_emails", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "ids": []
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/bring_in_review_emails",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "ids": []
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/dismiss_review_emails

Dismiss emails

Read and write keyPermanentIdempotency-Key

Dismisses emails from the person’s Review: they never come into the CRM and their copy is deleted. By id from list_email_review. Ask the person first, then call with confirm: true.

Body

idsarray of stringrequired

Email ids

confirmbooleanrequired

True once the person has confirmed

curl -X POST "https://api.crossingedge.com/v1/actions/dismiss_review_emails" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "ids": [],
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/dismiss_review_emails", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "ids": [],
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/dismiss_review_emails",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "ids": [],
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Telegram

Actions

Telegram chats, replies and links to records.

POST/actions/get_telegram

Get Telegram

Read key

The person’s Telegram in Crossing Edge: the workspace bot, whether their account is linked (and the link to do it), their Business chatbot and personal account, their filters, the groups the bot is in, and how many chats are tracked or waiting. Bot tokens, app keys and phone sign-in stay in Settings › Telegram, never in a chat.

curl -X POST "https://api.crossingedge.com/v1/actions/get_telegram" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_telegram", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_telegram",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/set_telegram_filters

Set Telegram filters

Read and write keyIdempotency-Key

The person’s own Telegram filters. onlySalesChats: only chats Jev judges to be sales come in (off: every chat). holdPrivateMessages: messages that look private wait for them before they come in (off: everything comes straight in).

Body

onlySalesChatsboolean

Only sales chats come in

holdPrivateMessagesboolean

Private-looking messages wait for you

curl -X POST "https://api.crossingedge.com/v1/actions/set_telegram_filters" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "onlySalesChats": true,
  "holdPrivateMessages": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/set_telegram_filters", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "onlySalesChats": true,
    "holdPrivateMessages": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/set_telegram_filters",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "onlySalesChats": True,
      "holdPrivateMessages": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/list_telegram_chats

List Telegram chats

Read key

Telegram chats brought into Crossing Edge (1:1 Business chats, groups with the workspace bot, personal account chats): people, last message, AI brief, linked records. The workspace’s tracked chats as far as the person can see; mine: true for their own; review: true for their chats waiting on them; ignored: true for ones they ignored; or one record’s.

Body

mineboolean

Only the person’s own chats

qstring

Search

kindstring

One of private group

reviewboolean

Their chats waiting for them to track or ignore

ignoredboolean

Chats they ignored

recordobject

Only the ones on this record

curl -X POST "https://api.crossingedge.com/v1/actions/list_telegram_chats" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "mine": true,
  "q": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/list_telegram_chats", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "mine": true,
    "q": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/list_telegram_chats",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "mine": True,
      "q": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/read_telegram_chat

Read Telegram chat

Read key

One Telegram chat with its messages, oldest first, and whether the person can reply to it from Crossing Edge (as themselves in a Business chat, or through the workspace bot in a group). Held private messages show only to their owner.

Body

idstringrequired

Chat id from list_telegram_chats

curl -X POST "https://api.crossingedge.com/v1/actions/read_telegram_chat" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "id": "101"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/read_telegram_chat", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "id": "101"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/read_telegram_chat",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "id": "101"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/reply_telegram_chat

Reply on Telegram

Read and write keyIdempotency-Key

Replies in one of the person’s own Telegram chats: as them in a Business chat, through the workspace bot (with their name) in a group. It goes to people outside the workspace: show the person the text, then call with confirm: true.

Body

idstringrequired

Chat id

textstringrequired

The message

confirmbooleanrequired

True once the person has seen it and said send

curl -X POST "https://api.crossingedge.com/v1/actions/reply_telegram_chat" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "id": "101",
  "text": "…",
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/reply_telegram_chat", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "id": "101",
    "text": "…",
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/reply_telegram_chat",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "id": "101",
      "text": "…",
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/set_telegram_chat_status

Track or ignore a Telegram chat

Read and write keyIdempotency-Key

Tracks one of the person’s Telegram chats (its messages come into the CRM) or ignores it (nothing more comes in; it can be tracked again).

Body

idstringrequired

Chat id

statusstringrequired

One of tracked ignored

curl -X POST "https://api.crossingedge.com/v1/actions/set_telegram_chat_status" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "id": "101",
  "status": "tracked"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/set_telegram_chat_status", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "id": "101",
    "status": "tracked"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/set_telegram_chat_status",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "id": "101",
      "status": "tracked"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/link_telegram_chat

Link Telegram chat

Read and write keyIdempotency-Key

Links one of the person’s Telegram chats to a record, so its messages show there: an existing contact, company, deal or workspace record (object + recordId), or a new contact made for someone in the chat (newContact). Linking a contact sets their Telegram handle and source Telegram.

Body

idstringrequired

Chat id

objectstring

contacts, companies, deals, or a workspace object id

recordIdnumber

Record id

newContactobject

Make a contact and link it. person: who in the chat (their name, @username or tgUserId; optional in a 1:1 chat)

curl -X POST "https://api.crossingedge.com/v1/actions/link_telegram_chat" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "id": "101"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/link_telegram_chat", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "id": "101"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/link_telegram_chat",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "id": "101"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/unlink_telegram_chat

Unlink Telegram chat

Read and write keyIdempotency-Key

Takes a record off one of the person’s Telegram chats; its messages stop showing there.

Body

idstringrequired

Chat id

objectstringrequired

Record object

recordIdnumberrequired

Record id

curl -X POST "https://api.crossingedge.com/v1/actions/unlink_telegram_chat" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "id": "101",
  "object": "deals",
  "recordId": 101
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/unlink_telegram_chat", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "id": "101",
    "object": "deals",
    "recordId": 101
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/unlink_telegram_chat",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "id": "101",
      "object": "deals",
      "recordId": 101
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/settle_held_telegram_message

Bring in or dismiss a held message

Read and write keyPermanentIdempotency-Key

A message held back as private in one of the person’s chats: bring: true brings it into the CRM, false dismisses it for good. By messageId from read_telegram_chat.

Body

idstringrequired

Chat id

messageIdnumberrequired

Message id

bringbooleanrequired

True to bring it in, false to dismiss it

curl -X POST "https://api.crossingedge.com/v1/actions/settle_held_telegram_message" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "id": "101",
  "messageId": 101,
  "bring": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/settle_held_telegram_message", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "id": "101",
    "messageId": 101,
    "bring": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/settle_held_telegram_message",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "id": "101",
      "messageId": 101,
      "bring": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/list_telegram_connections

List Telegram connections

Read key

Owners and admins: who in the workspace has connected Telegram (linked account, Business chatbot, personal account, groups) and which filters they turned off. Never their chats.

curl -X POST "https://api.crossingedge.com/v1/actions/list_telegram_connections" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const res = await fetch("https://api.crossingedge.com/v1/actions/list_telegram_connections", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/list_telegram_connections",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Webhooks

Actions

Incoming webhooks that bring leads in from forms and tools.

POST/actions/list_webhooks

List webhooks

Read key

The workspace’s incoming webhooks: addresses forms and tools post leads to. Each one’s status, address, the fields it has seen, and how many leads came in. Setting one up (mapping its fields) is done in Settings › Integrations › Webhooks.

curl -X POST "https://api.crossingedge.com/v1/actions/list_webhooks" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const res = await fetch("https://api.crossingedge.com/v1/actions/list_webhooks", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/list_webhooks",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/get_webhook_log

Get webhook log

Read key

One webhook’s recent posts, newest first: what each lead said, and whether it made a new contact, updated one, waited, or failed and why.

Body

webhookstring

Webhook name or id (optional when there is one)

limitnumber

How many (default 20)

curl -X POST "https://api.crossingedge.com/v1/actions/get_webhook_log" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "webhook": "…",
  "limit": 20
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_webhook_log", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "webhook": "…",
    "limit": 20
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_webhook_log",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "webhook": "…",
      "limit": 20
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/set_webhook_status

Pause or resume a webhook

Read and write keyIdempotency-Key

Pauses a webhook (leads wait in its log) or turns it back on (the waiting ones go in).

Body

webhookstring

Webhook name or id

statusstringrequired

One of paused active

curl -X POST "https://api.crossingedge.com/v1/actions/set_webhook_status" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "status": "paused"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/set_webhook_status", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "status": "paused"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/set_webhook_status",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "status": "paused"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/create_webhook

Create webhook

Read and write keyIdempotency-Key

Makes a new webhook: an address a form or tool posts leads to. It starts out listening: posts are kept as tests and nothing is written. Give the person the address to paste into their tool, ask them to send one lead, then call map_webhook.

Body

namestringrequired

Where the leads come from, like “Website form”. New contacts get it as their source.

curl -X POST "https://api.crossingedge.com/v1/actions/create_webhook" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Acme"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/create_webhook", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "name": "Acme"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/create_webhook",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "name": "Acme"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/map_webhook

Map and turn on a webhook

Read and write keyIdempotency-Key

Maps a webhook’s fields (from the tests it has received) onto contact and company fields, sets values every lead gets, and turns it on; on a live one it saves the change. Fields not given are matched by AI, as an import’s columns are. Leads arrive unassigned and the workspace’s automations always run on them: assign leads with an automation on new contacts (create_automation, owner step).

Body

webhookstringrequired

Webhook name or id

fieldsobject

Payload field (as list_webhooks shows it, e.g. "lead.email") → "contacts:email", "Contact · Email", "skip", or "new:Budget" for a new contact field. Unlisted fields are matched by AI.

valuesarray of object

Values every lead gets. Defaults to the source set to the webhook’s name.

onExistingstring

A contact already in the CRM (same email or phone): fill its blanks (default), overwrite, or leave it

One of fill overwrite skip

companyFromDomainboolean

Find or add the company from a work email (default true; free mail never makes one)

namestring

A new name for it

curl -X POST "https://api.crossingedge.com/v1/actions/map_webhook" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "webhook": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/map_webhook", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "webhook": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/map_webhook",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "webhook": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/preview_webhook

Preview a webhook lead

Read key

What a webhook’s latest post would become, written nowhere: the fields it would set, the contact it would update (same email or phone), the company its email finds or makes, and the automations that run.

Body

webhookstring

Webhook name or id

curl -X POST "https://api.crossingedge.com/v1/actions/preview_webhook" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "webhook": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/preview_webhook", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "webhook": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/preview_webhook",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "webhook": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/run_webhook_post_again

Run a webhook post again

Read and write keyIdempotency-Key

Runs one post from a webhook’s log again (one that failed, waited while paused, or was a test), by its id from get_webhook_log.

Body

webhookstring

Webhook name or id

poststringrequired

Post id from get_webhook_log

curl -X POST "https://api.crossingedge.com/v1/actions/run_webhook_post_again" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "post": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/run_webhook_post_again", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "post": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/run_webhook_post_again",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "post": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/new_webhook_address

New webhook address

Read and write keyPermanentIdempotency-Key

Gives a webhook a new address; the old one stops working at once, so the tool must be given the new one. Ask the person first, then call with confirm: true.

Body

webhookstring

Webhook name or id

confirmbooleanrequired

True once the person has confirmed

curl -X POST "https://api.crossingedge.com/v1/actions/new_webhook_address" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/new_webhook_address", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/new_webhook_address",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/delete_webhook

Delete webhook

Read and write keyPermanentIdempotency-Key

Deletes a webhook: its address stops working and its log goes. Contacts it brought in stay. Ask the person first, then call with confirm: true.

Body

webhookstringrequired

Webhook name or id

confirmbooleanrequired

True once the person has confirmed

curl -X POST "https://api.crossingedge.com/v1/actions/delete_webhook" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "webhook": "…",
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/delete_webhook", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "webhook": "…",
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/delete_webhook",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "webhook": "…",
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}

IndiaMART

Actions

IndiaMART enquiries arriving as leads.

POST/actions/get_indiamart

Get IndiaMART

Read key

How IndiaMART is connected: status, the key (last 4 only), the webhook address, what each enquiry becomes (mapping, values every lead gets, deal, call task), who gets each lead, and counts. IndiaMART fields: SENDER_NAME (Buyer name), SENDER_MOBILE (Mobile), SENDER_EMAIL (Email), SENDER_COMPANY (Buyer company), SENDER_CITY (City), SENDER_STATE (State), SENDER_PINCODE (Pincode), SENDER_COUNTRY_ISO (Country), SENDER_ADDRESS (Address), SUBJECT (Enquiry subject), QUERY_PRODUCT_NAME (Product), QUERY_MESSAGE (Message), QUERY_MCAT_NAME (Category), QUERY_TYPE (Enquiry type), QUERY_TIME (Enquired at), RECEIVER_MOBILE (Received on), CALL_DURATION (Call duration), SENDER_MOBILE_ALT (Alternate mobile), SENDER_PHONE (Landline), SENDER_PHONE_ALT (Alternate landline), SENDER_EMAIL_ALT (Alternate email), UNIQUE_QUERY_ID (Enquiry ID). Enquiry types: Direct enquiry, Buy lead, Phone call, Catalogue view, WhatsApp enquiry.

curl -X POST "https://api.crossingedge.com/v1/actions/get_indiamart" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_indiamart", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_indiamart",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/list_indiamart_enquiries

List IndiaMART enquiries

Read key

The latest IndiaMART enquiries and what each became: a new lead, updated, already in the CRM, failed (with why) or waiting. Newest first.

Body

limitnumber

How many (default 20, up to 200)

resultstring

Only this result

One of created updated skipped failed held

curl -X POST "https://api.crossingedge.com/v1/actions/list_indiamart_enquiries" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "limit": 20,
  "result": "created"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/list_indiamart_enquiries", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "limit": 20,
    "result": "created"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/list_indiamart_enquiries",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "limit": 20,
      "result": "created"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/connect_indiamart

Connect IndiaMART

Read and write keyIdempotency-Key

Connects IndiaMART, or replaces its CRM key. With a key (from IndiaMART Lead Manager › ⋮ › Import/Export Leads › Pull API) IndiaMART is checked at once and the answer says how many enquiries the last day had; with no key it connects for the webhook only. A new connection then needs update_indiamart to go live.

Body

keystring

The CRM key, when the person gave one

curl -X POST "https://api.crossingedge.com/v1/actions/connect_indiamart" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "key": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/connect_indiamart", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "key": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/connect_indiamart",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "key": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/update_indiamart

Update IndiaMART

Read and write keyIdempotency-Key

Changes what IndiaMART enquiries become and who gets them, and switches a new connection on. Pass only what changes; the rest stays. - map: { IndiaMART field: "object:field" | "skip" | { new: { object, label, type } } }, e.g. { "QUERY_PRODUCT_NAME": "contacts:note", "QUERY_MCAT_NAME": { "new": { "object": "contacts", "label": "Category", "type": "singleSelect" } } }. - everyLeadGets: [{ field: "contacts:source", value: "IndiaMART" }] replaces the list. - owners: { mode: "none" } | { mode: "one", member } | { mode: "rotate", members: [...] } | { mode: "rules", rules: [{ when: [{ field: "SENDER_CITY", op: "is", value: "Mumbai, Pune" }], to: [...] }], fallback: [...] }. Members by email or name. Rule fields: SENDER_CITY, SENDER_STATE, SENDER_PINCODE, SENDER_COUNTRY_ISO, QUERY_PRODUCT_NAME, QUERY_MCAT_NAME, QUERY_TYPE, SUBJECT, QUERY_MESSAGE, SENDER_COMPANY, RECEIVER_MOBILE; ops: is, isNot, contains, startsWith; a comma list means any of. - deal: { on, pipelineId, stage }; callTask: { on, dueMinutes }; existingRecords: fill | overwrite | skip; automations: true/false. - pastDays (7, 30, 90 or 365): also bring in past enquiries, once. IndiaMART fields: SENDER_NAME (Buyer name), SENDER_MOBILE (Mobile), SENDER_EMAIL (Email), SENDER_COMPANY (Buyer company), SENDER_CITY (City), SENDER_STATE (State), SENDER_PINCODE (Pincode), SENDER_COUNTRY_ISO (Country), SENDER_ADDRESS (Address), SUBJECT (Enquiry subject), QUERY_PRODUCT_NAME (Product), QUERY_MESSAGE (Message), QUERY_MCAT_NAME (Category), QUERY_TYPE (Enquiry type), QUERY_TIME (Enquired at), RECEIVER_MOBILE (Received on), CALL_DURATION (Call duration), SENDER_MOBILE_ALT (Alternate mobile), SENDER_PHONE (Landline), SENDER_PHONE_ALT (Alternate landline), SENDER_EMAIL_ALT (Alternate email), UNIQUE_QUERY_ID (Enquiry ID). Enquiry types: Direct enquiry, Buy lead, Phone call, Catalogue view, WhatsApp enquiry.

Body

mapobject

IndiaMART field → target

everyLeadGetsarray of object

Values every lead gets

ownersobject

Who gets each lead

dealobject

{ on, pipelineId, stage }

callTaskobject

{ on, dueMinutes }

existingRecordsstring

One of fill overwrite skip

automationsboolean

Run automations on each lead

pastDaysnumber

7, 30, 90 or 365

curl -X POST "https://api.crossingedge.com/v1/actions/update_indiamart" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "map": {},
  "everyLeadGets": []
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/update_indiamart", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "map": {},
    "everyLeadGets": []
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/update_indiamart",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "map": {},
      "everyLeadGets": []
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/set_indiamart_status

Pause or resume IndiaMART

Read and write keyIdempotency-Key

Pauses IndiaMART (enquiries sent by webhook are held and come in on resume) or resumes it.

Body

statusstringrequired

One of paused active

curl -X POST "https://api.crossingedge.com/v1/actions/set_indiamart_status" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "status": "paused"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/set_indiamart_status", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "status": "paused"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/set_indiamart_status",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "status": "paused"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/check_indiamart_now

Check IndiaMART now

Read and write keyIdempotency-Key

Asks IndiaMART for new enquiries now. IndiaMART allows one check every 5 minutes; if it is too soon, the answer says when the next one is allowed.

curl -X POST "https://api.crossingedge.com/v1/actions/check_indiamart_now" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'
const res = await fetch("https://api.crossingedge.com/v1/actions/check_indiamart_now", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({}),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/check_indiamart_now",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/retry_indiamart_enquiry

Retry IndiaMART enquiry

Read and write keyIdempotency-Key

Takes a failed or waiting IndiaMART enquiry again, by its id from list_indiamart_enquiries.

Body

idstringrequired

Enquiry id

curl -X POST "https://api.crossingedge.com/v1/actions/retry_indiamart_enquiry" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "id": "101"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/retry_indiamart_enquiry", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "id": "101"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/retry_indiamart_enquiry",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "id": "101"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/new_indiamart_webhook

New IndiaMART webhook address

Read and write keyPermanentIdempotency-Key

Makes a new webhook address for IndiaMART; the old one stops working at once, so the new one must be pasted into IndiaMART’s Push API page. For an address shared by mistake. Ask the person first, then call with confirm: true.

Body

confirmbooleanrequired

True once the person has confirmed

curl -X POST "https://api.crossingedge.com/v1/actions/new_indiamart_webhook" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/new_indiamart_webhook", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/new_indiamart_webhook",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/disconnect_indiamart

Disconnect IndiaMART

Read and write keyPermanentIdempotency-Key

Disconnects IndiaMART: the key, mapping, owners and enquiry log go; leads already made stay. Ask the person first, then call with confirm: true.

Body

confirmbooleanrequired

True once the person has confirmed

curl -X POST "https://api.crossingedge.com/v1/actions/disconnect_indiamart" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "confirm": true
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/disconnect_indiamart", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "confirm": true
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/disconnect_indiamart",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "confirm": True
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Events

Actions

Event mode: who was met at a conference or trade fair.

POST/actions/list_events

List events

Read key

The workspace’s events in event mode (conferences, trade fairs), running ones first: their lead source, how many people were captured at each by you and in total, and the link to the capture page.

curl -X POST "https://api.crossingedge.com/v1/actions/list_events" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const res = await fetch("https://api.crossingedge.com/v1/actions/list_events", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/list_events",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/get_event

Get event

Read key

One event and everyone captured at it: who, who captured them, how (QR, card photo or typed) and when, newest first. Use it for "who did we meet at TOKEN2049".

Body

eventstringrequired

Event name or id

curl -X POST "https://api.crossingedge.com/v1/actions/get_event" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "event": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_event", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "event": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_event",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "event": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/create_event

Create event

Read and write keyIdempotency-Key

Starts an event in event mode and returns its capture-page link (open it on a phone to scan QR codes and cards). source is the lead source captures start on: one of the choices get_schema lists for contacts.source, or a new one with addSource: true (owners and admins).

Body

namestringrequired

Event name, e.g. TOKEN2049

sourcestring

Lead source captures start on

addSourceboolean

Add source as a new lead source choice first

curl -X POST "https://api.crossingedge.com/v1/actions/create_event" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Acme"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/create_event", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "name": "Acme"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/create_event",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "name": "Acme"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/end_event

End event

Read and write keyIdempotency-Key

Ends an event so its link stops capturing, or reopens it with reopen: true. Whoever started it, or an owner or admin.

Body

eventstringrequired

Event name or id

reopenboolean

Reopen an ended event

curl -X POST "https://api.crossingedge.com/v1/actions/end_event" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "event": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/end_event", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "event": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/end_event",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "event": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/capture_at_event

Capture at event

Read and write keyIdempotency-Key

Adds someone met at an event: either an existing contact (contactId), or a new lead from their details, owned by you and on the event’s source. Either way they are counted at the event and get a “Met at …” note. A new lead needs a first name and an email, a phone, or a Telegram handle (someone known only by their Telegram handle is matched when they message).

Body

eventstringrequired

Event name or id

contactIdnumber

An existing contact, instead of new details

firstNamestring

First name

lastNamestring

Last name

emailstring

Email

phonestring

Phone

jobTitlestring

Job title

companyIdnumber

Their company, if already in the CRM

telegramstring

Telegram handle, without the @

xstring

X (Twitter) handle, without the @

linkedinstring

LinkedIn profile URL

notestring

Anything else worth keeping, added to the note

methodstring

How they were captured; default typed

One of qr photo typed

curl -X POST "https://api.crossingedge.com/v1/actions/capture_at_event" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "event": "…"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/capture_at_event", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "event": "…"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/capture_at_event",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "event": "…"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Exports

Actions

Spreadsheets of records.

POST/actions/export_records

Export records

Read key

Exports records as a spreadsheet and returns a download link (kept 7 days). One object gives a CSV; several give a zip with one CSV per object. Give record ids to export only those (search_records or search_contacts finds them), and field keys from get_schema to choose columns; otherwise every record the person can see, with every field. Calculated fields are left out. Needs the Export records permission; every export is logged.

Body

objectsarray of objectrequired

What to export, one entry per object

curl -X POST "https://api.crossingedge.com/v1/actions/export_records" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "objects": []
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/export_records", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "objects": []
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/export_records",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "objects": []
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}

Reports and schema

Actions

Reports, the workspace schema and queries.

POST/actions/report_guide

Report guide

Read key

How reports work: the sandboxed runtime, window.crossingEdge, the query language, making a dashboard interactive (drill-downs, filters, tabs, dialogs) and the house style. Read this before building.

curl -X POST "https://api.crossingedge.com/v1/actions/report_guide" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const res = await fetch("https://api.crossingedge.com/v1/actions/report_guide", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/report_guide",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/get_schema

Get schema

Read key

The workspace data model: every object and field (with types and choices), pipelines and stages, members, currency and today’s date.

curl -X POST "https://api.crossingedge.com/v1/actions/get_schema" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_schema", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_schema",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/run_query

Run query

Read key

Runs one report query and returns the answer, exactly as a report would get it. Use it to check numbers before publishing.

Body

queryobjectrequired

A report query. See report_guide for the full language.

curl -X POST "https://api.crossingedge.com/v1/actions/run_query" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "query": {}
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/run_query", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "query": {}
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/run_query",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "query": {}
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/list_reports

List reports

Read key

Reports in the workspace this person can see: their own and the shared ones.

curl -X POST "https://api.crossingedge.com/v1/actions/list_reports" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
const res = await fetch("https://api.crossingedge.com/v1/actions/list_reports", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/list_reports",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={},
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/get_report

Get report

Read key

One report with its full HTML, to read or change it.

Body

idstringrequired

Report id

curl -X POST "https://api.crossingedge.com/v1/actions/get_report" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "id": "101"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/get_report", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "id": "101"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/get_report",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "id": "101"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/check_report

Check report

Read key

Checks a native report spec and works out every figure on it for a period and the one before, exactly as the page will show them. Run it before create_report and read the numbers back.

Body

specobjectrequired

The report spec (see report_guide)

periodobject

{ kind: week | month | quarter | year | custom, year?, quarter?, from?, to? }. Default: the spec’s, else this month

pipelinestring

A pipeline name, as the pipeline picker would set it

filtersarray of object

Filter bar filters on the spec’s object

curl -X POST "https://api.crossingedge.com/v1/actions/check_report" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "spec": {}
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/check_report", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "spec": {}
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/check_report",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}"},
    json={
      "spec": {}
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/create_report

Create report

Read and write keyIdempotency-Key

Publishes a new report into Crossing Edge. Returns its URL. Private to its author unless shared is true. Prefer a native report (spec): the app draws it with Insights’ own pieces. Use html only for what a spec cannot draw.

Body

namestringrequired

Short title, e.g. "Pipeline health"

descriptionstring

One line on what it answers

specobject

A native report spec (see report_guide). Check it with check_report first

htmlstring

Instead of a spec: the complete, self-contained HTML page

sharedboolean

Show it to everyone in the workspace (each sees only their own data access)

curl -X POST "https://api.crossingedge.com/v1/actions/create_report" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "name": "Acme"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/create_report", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "name": "Acme"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/create_report",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "name": "Acme"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}
POST/actions/update_report

Update report

Read and write keyIdempotency-Key

Changes a report: any of its name, description, spec, HTML or sharing. Only its author, an owner or an admin can. A spec replaces HTML and the other way round. To change part of an HTML report, send edits rather than the whole page: read it with get_report, then give each piece of text to find (copied exactly, appearing once) and what replaces it. A long page written out in full may not fit in one reply.

Body

idstringrequired

Report id

namestring

New title

descriptionstring

New description

specobject

The complete new spec

htmlstring

The complete new HTML

editsarray of object

Changes to part of the HTML page, applied in order: each find is exact text from the current page that appears once, replaced by replace

sharedboolean
curl -X POST "https://api.crossingedge.com/v1/actions/update_report" \
  -H "Authorization: Bearer $CROSSING_EDGE_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "id": "101"
}'
const res = await fetch("https://api.crossingedge.com/v1/actions/update_report", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CROSSING_EDGE_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "id": "101"
  }),
});
const { data, error } = await res.json();
import os, uuid, requests

res = requests.post(
    "https://api.crossingedge.com/v1/actions/update_report",
    headers={"Authorization": f"Bearer {os.environ['CROSSING_EDGE_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
    json={
      "id": "101"
    },
)
data = res.json()["data"]
Response · 200
{
  "data": {
    "id": 101,
    "…": "…"
  },
  "request_id": "req_7c1f0e2a9b4d"
}