Developers
Set your API contextPick a region and space ID once. Every sample fills in your base URL.
Where do I find these?

In Coevera: open your space's API application and choose Show Access. It shows the space ID and the base URL, whose host starts with your region.

From the API: if you know the space ID, the discovery endpoint GET /api/discovery/spaces/{space_id} returns its region and base URLs, without credentials.

Only the region and space ID are kept, in this browser. Never paste a key or password here.

More in the quickstart

WebhooksFiltering and options

Filtering and options

Narrow and shape what a webhook delivers with its options, from filter and on-field-change to load-only, chunk_size and skip_keys.

Answer

A webhook's options object narrows and shapes deliveries. Per entity, filter and filter-op choose which records are delivered, on-field-change delivers only when listed fields changed, and load-only and expand shape the record. At the top level, chunk_size (1 to 100), chunk_delay, skip_keys and custom_entity_api_name apply. Option keys use load-only with a hyphen; load_only is refused.

options is optional: without it, a webhook delivers every record of the events it subscribes to, as the REST API returns it. The API checks every key when you create or update a webhook and refuses one it does not know with a 400, naming the key (errors). The options follow the REST API's list parameters, which querying describes, and are a field of the Webhooks entity.

This update sets a per-entity load-only and two top-level options, chunk_size and skip_keys:

# The events and options you send replace the webhook's: send the whole list and object.
curl -sS --fail-with-body -X PATCH "$COEVERA_BASE/entities/Webhooks/$WEBHOOK_ID" \
  -u "$COEVERA_API_KEY:$COEVERA_API_SECRET" \
  -H "Content-Type: application/json" \
  -d @- <<JSON
{
  "events": ["Opportunity.Won", "Opportunity.Lost", "Opportunity.Move"],
  "options": {
    "entity": {
      "Opportunity": { "load-only": ["id", "name", "owner_id", "step_id", "value", "revision"] }
    },
    "chunk_size": 50,
    "skip_keys": ["northwind-sync"]
  }
}
JSON
echo
// The events and options you send replace the webhook's: send the whole list and object.
await coevera("PATCH", `/entities/Webhooks/${webhookId}`, {
  events: ["Opportunity.Won", "Opportunity.Lost", "Opportunity.Move"],
  options: {
    entity: { Opportunity: { "load-only": ["id", "name", "owner_id", "step_id", "value", "revision"] } },
    chunk_size: 50,
    skip_keys: ["northwind-sync"],
  },
});
# The events and options you send replace the webhook's: send the whole list and object.
coevera(
    "PATCH",
    f"/entities/Webhooks/{webhook_id}",
    json={
        "events": ["Opportunity.Won", "Opportunity.Lost", "Opportunity.Move"],
        "options": {
            "entity": {"Opportunity": {"load-only": ["id", "name", "owner_id", "step_id", "value", "revision"]}},
            "chunk_size": 50,
            "skip_keys": ["northwind-sync"],
        },
    },
)
# The events and options you send replace the webhook's: send the whole list and object.
jq -n --arg id "$WEBHOOK_ID" '{
  query: "mutation UpdateWebhook($input: UpdateWebhookInput!) { updateWebhook(input: $input) { webhook { id events options } } }",
  variables: {
    input: {
      id: $id,
      events: ["OpportunityWon", "OpportunityLost", "OpportunityMove"],
      options: ({
        entity: { Opportunity: { "load-only": ["id", "name", "owner_id", "step_id", "value", "revision"] } },
        chunk_size: 50,
        skip_keys: ["northwind-sync"]
      } | tojson)
    }
  }
}' | gql
// The events and options you send replace the webhook's: send the whole list and object.
await gql(
  `mutation UpdateWebhook($input: UpdateWebhookInput!) {
    updateWebhook(input: $input) { webhook { id events options } }
  }`,
  {
    input: {
      id: webhookId,
      events: ["OpportunityWon", "OpportunityLost", "OpportunityMove"],
      options: JSON.stringify({
        entity: { Opportunity: { "load-only": ["id", "name", "owner_id", "step_id", "value", "revision"] } },
        chunk_size: 50,
        skip_keys: ["northwind-sync"],
      }),
    },
  },
);
# The events and options you send replace the webhook's: send the whole list and object.
gql(
    """
    mutation UpdateWebhook($input: UpdateWebhookInput!) {
      updateWebhook(input: $input) { webhook { id events options } }
    }
    """,
    {
        "input": {
            "id": webhook_id,
            "events": ["OpportunityWon", "OpportunityLost", "OpportunityMove"],
            "options": json.dumps({
                "entity": {"Opportunity": {"load-only": ["id", "name", "owner_id", "step_id", "value", "revision"]}},
                "chunk_size": 50,
                "skip_keys": ["northwind-sync"],
            }),
        }
    },
)

Top-level options

Key What it does
entity Options for the record in entity, per entity: {"Opportunity": {…}}. The keys are entity names as the events use them; an unknown entity is refused.
related_entity expand for the document in related_entity of a DocumentLinked event, per event entity: {"Opportunity": {"expand": ["owner"]}}. Only expand is accepted.
chunk_size How many events one delivery carries: 1 to 100, 100 by default. 0 or 101 is refused.
chunk_delay Seconds between chunks: chunk N, counted from 0, is sent N × chunk_delay seconds later. 0 by default; a negative value is refused.
skip_keys Keys that stop this webhook firing: a write sent with the header WebHook-Skip-Key set to one of them does not fire it.
custom_entity_api_name For CustomEntity events, the custom entities that fire this webhook, such as ["CE_Shipment"]. All of them by default.

Per-entity options

Under entity.<Entity>, five keys are accepted, in the REST API's names (snake case for fields, a hyphen in load-only, filter-op and on-field-change):

Key What it does
filter Deliver only the records that match, in the REST API's filter form: {"name": "Northwind"}, or a list of values for any of them. A field the entity does not have is refused.
filter-op The operator per filtered field, such as {"name": "contains"}; eq by default. The operators are those of the REST API.
on-field-change Deliver a record only if one of these fields changed in that change: ["step_id", "value"]. An unknown field name is refused.
load-only The fields the record in the delivery carries. Keep id and revision if you deduplicate on them.
expand Related records to include in full, such as ["owner"].

Warning

load-only takes a hyphen. load_only, which some REST query parameters tolerate, is refused here with a 400.

on-field-change narrows every event

on-field-change applies to every event of that entity the webhook subscribes to, not only to Update: a Create, a Won or a Delete is delivered only if one of the listed fields changed in that same change. Subscribe to Opportunity.Won with on-field-change: ["value"], and a win that leaves the value alone is not delivered. Use a second webhook for events that must always arrive.

It works for these entities: Account, Contact, Lead, Opportunity, Task, Appointment, product line items (OpptyProductRelation), Project, Quote, Email, and custom entities. OnlineForm is accepted but has no events. Any other entity, such as Product, Memo or Note, is refused.

Reading and changing options

  • An update replaces options as a whole: send every key you want to keep, as the sample above does.
  • List webhooks without load-only: with it, options comes back as {}.
  • In GraphQL, options is a JSON string, in the input and in the response.
  • options: null is refused; send {} to clear them.

Limits

  • related_entity takes only expand; there is no load-only or filter for the document.
  • The filter applies to the record as it is when the delivery is built, not when it changed.
  • Records the webhook's owner cannot read are left out of deliveries. A webhook registered with an API application's credentials has no owner, so it delivers every record.