Skip to content

Webhook Subscription Management

This guide explains how to create and remove webhook subscriptions. HappyColis supports two authentication modes — Integration App tokens and OAuth Client tokens — each with its own set of mutations.

Authentication Modes

Integration App (INTEGRATION)

An Integration App uses a dedicated app token obtained via your client_id / client_secret. You must have the edit_integrations scope to manage webhooks.

OAuth Client (OAUTH_CLIENT)

An OAuth client uses a short-lived access token obtained via the OAuth 2.0 client credentials flow. No extra scope is required beyond having a valid token.

The IntegrationType stored on each subscription (INTEGRATION or OAUTH_CLIENT) determines which removal mutation you must use. You can only remove subscriptions created by your own integration/client.


Creating a Subscription

Input type: IntegrationWebhookInput

FieldTypeRequiredDescription
endPointString (URL)YesHTTPS URL that will receive POST requests
typeString (WebhookType)NoEvent type to subscribe to (e.g. order/created)
headersJSONObjectNoCustom HTTP headers sent with every delivery
idIDNoReserved — not used on create
integrationIdIDNoReserved — not used on create

endPoint must be a valid URL. Custom headers are forwarded verbatim alongside Content-Type: application/json and the signature header.


For Integration Apps — integrationWebhookCreate

Required scope: edit_integrationsToken type: Integration App token

graphql
mutation IntegrationWebhookCreate($input: IntegrationWebhookInput!) {
  integrationWebhookCreate(input: $input) {
    id
    type
    health
    endPoint
  }
}

Variables:

json
{
  "input": {
    "endPoint": "https://your-app.com/webhooks/happycolis",
    "type": "order/created",
    "headers": {
      "X-Secret-Token": "my-secret"
    }
  }
}

curl:

bash
curl -X POST https://api-v3.happycolis.com/graphql \
  -H "Authorization: Bearer $INTEGRATION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation IntegrationWebhookCreate($input: IntegrationWebhookInput!) { integrationWebhookCreate(input: $input) { id type health endPoint } }",
    "variables": {
      "input": {
        "endPoint": "https://your-app.com/webhooks/happycolis",
        "type": "order/created"
      }
    }
  }'

For OAuth Clients — oauthWebhookCreate

Token type: OAuth Client Credentials token

graphql
mutation OauthWebhookCreate($input: IntegrationWebhookInput!) {
  oauthWebhookCreate(input: $input) {
    id
    type
    health
    endPoint
  }
}

Variables:

json
{
  "input": {
    "endPoint": "https://your-app.com/webhooks/happycolis",
    "type": "shipment/created"
  }
}

curl:

bash
curl -X POST https://api-v3.happycolis.com/graphql \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation OauthWebhookCreate($input: IntegrationWebhookInput!) { oauthWebhookCreate(input: $input) { id type health endPoint } }",
    "variables": {
      "input": {
        "endPoint": "https://your-app.com/webhooks/happycolis",
        "type": "shipment/created"
      }
    }
  }'

Node.js example:

javascript
const createWebhook = async (accessToken, endPoint, type) => {
  const response = await fetch('https://api-v3.happycolis.com/graphql', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query: `
        mutation OauthWebhookCreate($input: IntegrationWebhookInput!) {
          oauthWebhookCreate(input: $input) {
            id
            type
            health
            endPoint
          }
        }
      `,
      variables: { input: { endPoint, type } },
    }),
  });

  const { data, errors } = await response.json();
  if (errors) throw new Error(errors[0].message);
  return data.oauthWebhookCreate;
};

Removing a Subscription

Pass the id returned by the create mutation. You can only remove subscriptions that belong to the calling integration or OAuth client.

For Integration Apps — integrationWebhookRemove

graphql
mutation IntegrationWebhookRemove($id: String!) {
  integrationWebhookRemove(id: $id) {
    id
    type
    endPoint
  }
}

Variables:

json
{ "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" }

Errors:

ConditionError
Webhook not foundFORBIDDEN: You can't remove this webhook: webhook not found
Webhook belongs to a different integrationFORBIDDEN: You can't remove this webhook: integrationId or integrationType mismatch

For OAuth Clients — oauthWebhookRemove

graphql
mutation OauthWebhookRemove($id: String!) {
  oauthWebhookRemove(id: $id) {
    id
    type
    endPoint
  }
}

Variables:

json
{ "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" }

Errors:

ConditionError
Webhook not foundFORBIDDEN: You can't remove this webhook: webhook not found
Webhook belongs to a different OAuth clientFORBIDDEN: You can't remove this webhook: integrationId or integrationType mismatch

Webhook Health States

Each subscription has a health field that reflects delivery status.

ValueDescription
HEALTHYAll recent deliveries succeeded. The queue is active.
FAILINGOne or more deliveries have failed. The queue is blocked and no further messages will be delivered to this endpoint until the issue is resolved.

When a queue enters the BLOCKED state, new events are still accepted into the queue but delivery is paused. Check your endpoint for connectivity issues and contact support if the health does not recover.


Uniqueness Constraint

Each integration may only have one active subscription per event type. Attempting to create a duplicate subscription (same integrationId + type) will result in a conflict error from the database.


Integration vs OAuth Mode Comparison

FeatureIntegration AppOAuth Client
Mutation (create)integrationWebhookCreateoauthWebhookCreate
Mutation (remove)integrationWebhookRemoveoauthWebhookRemove
Required scopeedit_integrations(none beyond valid token)
integrationType storedINTEGRATIONOAUTH_CLIENT
Token guardAppPayloadGuardClientPayloadGuard
Can remove other's webhooksNoNo

See Also

HappyColis API Documentation