Skip to content
Sections

Guest communications

Ingest a signed provider inbound message

POST/guest-communication-providers/{providerId}/events/inbound

Authenticates the provider event, deduplicates its event identifier, and appends the inbound message to the matching venue conversation. Hallify HMAC profile guest-provider uses HMAC-SHA256. Canonical input: RFC3339 timestamp + "." + JSON.stringify(parsed DTO). Send x-hallify-timestamp as rfc3339; timestamps outside ±300 seconds are stale. Send x-hallify-signature as base64url; comparison is timing-safe. Secret handling: Use the issued secret as UTF-8 text. Accepted Content-Type: application/json. Malformed input: A malformed signature returns 401 GUEST_PROVIDER_WEBHOOK_UNAUTHORIZED. Stale input: A timestamp outside the 300-second window returns 401 GUEST_PROVIDER_WEBHOOK_UNAUTHORIZED. Repeated delivery: Signatures are not rejected solely for repetition; provider message and event identifiers control domain deduplication.

Authentication

x-hallify-signature: <HALLIFY_SIGNATURE>

HMAC-SHA256 signature credential. Each operation documents its exact protocol through x-hallify-hmac metadata and the operation description.

Connection guide

Parameters

providerIdPath · Required

Hallify UUID whose ownership is validated against every parent tenant and aggregate in this route before the selected resource is exposed or changed.

string · uuid
Full definition
{
  "type": "string",
  "format": "uuid",
  "example": "9b6163a8-afea-4877-818b-8e2ae28a2845"
}
x-hallify-timestampHeader · Required

rfc3339 timestamp; accepted clock skew is ±300 seconds.

string
Full definition
{
  "type": "string",
  "example": "example"
}

Request body

Required

Provider event and message identifiers, source contact, optional subject, message body, and occurrence timestamp consumed as the signed inbound message payload.

application/json

GuestProviderInboundMessageDto
Full definition
{
  "$ref": "#/components/schemas/GuestProviderInboundMessageDto"
}

Responses

200Returns the matched conversation and whether the provider event was newly applied or replayed.
GuestProviderWebhooksInboundResultDto
Full definition
{
  "$ref": "#/components/schemas/GuestProviderWebhooksInboundResultDto"
}
Example response · 200 · application/json
{
  "accepted": true,
  "messageId": "6656e43a-a70a-4ac5-8f2c-e049d62f80c7",
  "conversationId": "d6993a6a-84c6-4c36-8812-5d181ae025cd",
  "duplicate": true
}
400Provider identifier or inbound message payload is invalid
TranslatedErrorDto
Full definition
{
  "$ref": "#/components/schemas/TranslatedErrorDto"
}
Example response · 400 · application/json
{
  "statusCode": 400,
  "error": "errors:http.badRequest",
  "code": "HTTP_BAD_REQUEST",
  "message": "errors:http.badRequest",
  "translationKey": "errors:http.badRequest"
}
401Provider is unavailable or its HMAC signature is invalid or stale
TranslatedErrorDto
Full definition
{
  "$ref": "#/components/schemas/TranslatedErrorDto"
}
Example response · 401 · application/json
{
  "statusCode": 401,
  "error": "errors:http.unauthorized",
  "code": "HTTP_UNAUTHORIZED",
  "message": "errors:http.unauthorized",
  "translationKey": "errors:http.unauthorized"
}
503Provider signing secret could not be decrypted
TranslatedErrorDto
Full definition
{
  "$ref": "#/components/schemas/TranslatedErrorDto"
}
Example response · 503 · application/json
{
  "statusCode": 503,
  "error": "errors:http.serviceUnavailable",
  "code": "HTTP_SERVICE_UNAVAILABLE",
  "message": "errors:http.serviceUnavailable",
  "translationKey": "errors:http.serviceUnavailable"
}

Schemas

GuestProviderInboundMessageDto

Authenticates the provider event, deduplicates its event identifier, and appends the inbound message to the matching venue conversation.

externalEventIdRequired

Opaque identifier for external event associated with guest provider inbound message; clients must not assume UUID syntax. Accepted values enforce maximum length 191.

string
Full definition
{
  "type": "string",
  "maxLength": 191,
  "description": "Opaque identifier for external event associated with guest provider inbound message; clients must not assume UUID syntax. Accepted values enforce maximum length 191.",
  "example": "Synthetic example"
}
externalMessageIdRequired

Opaque identifier for external message associated with guest provider inbound message; clients must not assume UUID syntax. Accepted values enforce maximum length 191.

string
Full definition
{
  "type": "string",
  "maxLength": 191,
  "description": "Opaque identifier for external message associated with guest provider inbound message; clients must not assume UUID syntax. Accepted values enforce maximum length 191.",
  "example": "Synthetic example"
}
contactValueRequired

Contact value interpreted according to the sibling type, kind, unit, or policy fields in guest provider inbound message. Accepted values enforce maximum length 254.

string
Full definition
{
  "type": "string",
  "maxLength": 254,
  "description": "Contact value interpreted according to the sibling type, kind, unit, or policy fields in guest provider inbound message. Accepted values enforce maximum length 254.",
  "example": "Synthetic example"
}
subjectOptional

Human-readable subject line used by guest provider inbound message. Accepted values enforce maximum length 255.

string
Full definition
{
  "type": "string",
  "maxLength": 255,
  "description": "Human-readable subject line used by guest provider inbound message. Accepted values enforce maximum length 255.",
  "example": "Synthetic example"
}
bodyRequired

Human-authored body content stored with guest provider inbound message. Accepted values enforce minimum length 1 and maximum length 5000.

string
Full definition
{
  "type": "string",
  "minLength": 1,
  "maxLength": 5000,
  "description": "Human-authored body content stored with guest provider inbound message. Accepted values enforce minimum length 1 and maximum length 5000.",
  "example": "Synthetic example"
}
occurredAtRequired

RFC 3339 timestamp for occurred at; offsets represent the same absolute instant.

string · date-time
Full definition
{
  "type": "string",
  "format": "date-time",
  "description": "RFC 3339 timestamp for occurred at; offsets represent the same absolute instant.",
  "example": "2026-01-15T12:00:00.000Z"
}
Full definition
{
  "type": "object",
  "properties": {
    "externalEventId": {
      "type": "string",
      "maxLength": 191,
      "description": "Opaque identifier for external event associated with guest provider inbound message; clients must not assume UUID syntax. Accepted values enforce maximum length 191.",
      "example": "Synthetic example"
    },
    "externalMessageId": {
      "type": "string",
      "maxLength": 191,
      "description": "Opaque identifier for external message associated with guest provider inbound message; clients must not assume UUID syntax. Accepted values enforce maximum length 191.",
      "example": "Synthetic example"
    },
    "contactValue": {
      "type": "string",
      "maxLength": 254,
      "description": "Contact value interpreted according to the sibling type, kind, unit, or policy fields in guest provider inbound message. Accepted values enforce maximum length 254.",
      "example": "Synthetic example"
    },
    "subject": {
      "type": "string",
      "maxLength": 255,
      "description": "Human-readable subject line used by guest provider inbound message. Accepted values enforce maximum length 255.",
      "example": "Synthetic example"
    },
    "body": {
      "type": "string",
      "minLength": 1,
      "maxLength": 5000,
      "description": "Human-authored body content stored with guest provider inbound message. Accepted values enforce minimum length 1 and maximum length 5000.",
      "example": "Synthetic example"
    },
    "occurredAt": {
      "type": "string",
      "format": "date-time",
      "description": "RFC 3339 timestamp for occurred at; offsets represent the same absolute instant.",
      "example": "2026-01-15T12:00:00.000Z"
    }
  },
  "required": [
    "externalEventId",
    "externalMessageId",
    "contactValue",
    "body",
    "occurredAt"
  ],
  "description": "Authenticates the provider event, deduplicates its event identifier, and appends the inbound message to the matching venue conversation.",
  "example": {
    "externalEventId": "Synthetic example",
    "externalMessageId": "Synthetic example",
    "contactValue": "Synthetic example",
    "body": "Synthetic example",
    "occurredAt": "2026-01-15T12:00:00.000Z"
  }
}
GuestProviderWebhooksInboundResultDto

Returns the matched conversation and whether the provider event was newly applied or replayed.

acceptedRequired

Allowed accepted for guest provider webhooks inbound: true.

boolean
Full definition
{
  "type": "boolean",
  "enum": [
    true
  ],
  "description": "Allowed accepted for guest provider webhooks inbound: true.",
  "example": true
}
messageIdRequired

Hallify UUID identifying message associated with guest provider webhooks inbound.

string · uuid
Full definition
{
  "type": "string",
  "format": "uuid",
  "description": "Hallify UUID identifying message associated with guest provider webhooks inbound.",
  "example": "6656e43a-a70a-4ac5-8f2c-e049d62f80c7"
}
conversationIdRequired

Hallify UUID identifying conversation associated with guest provider webhooks inbound.

string · uuid
Full definition
{
  "type": "string",
  "format": "uuid",
  "description": "Hallify UUID identifying conversation associated with guest provider webhooks inbound.",
  "example": "d6993a6a-84c6-4c36-8812-5d181ae025cd"
}
duplicateRequired

Whether the submitted event was already accepted and handled as a duplicate.

boolean
Full definition
{
  "type": "boolean",
  "description": "Whether the submitted event was already accepted and handled as a duplicate.",
  "example": true
}
Full definition
{
  "type": "object",
  "required": [
    "accepted",
    "messageId",
    "conversationId",
    "duplicate"
  ],
  "properties": {
    "accepted": {
      "type": "boolean",
      "enum": [
        true
      ],
      "description": "Allowed accepted for guest provider webhooks inbound: true.",
      "example": true
    },
    "messageId": {
      "type": "string",
      "format": "uuid",
      "description": "Hallify UUID identifying message associated with guest provider webhooks inbound.",
      "example": "6656e43a-a70a-4ac5-8f2c-e049d62f80c7"
    },
    "conversationId": {
      "type": "string",
      "format": "uuid",
      "description": "Hallify UUID identifying conversation associated with guest provider webhooks inbound.",
      "example": "d6993a6a-84c6-4c36-8812-5d181ae025cd"
    },
    "duplicate": {
      "type": "boolean",
      "description": "Whether the submitted event was already accepted and handled as a duplicate.",
      "example": true
    }
  },
  "description": "Returns the matched conversation and whether the provider event was newly applied or replayed.",
  "example": {
    "accepted": true,
    "messageId": "6656e43a-a70a-4ac5-8f2c-e049d62f80c7",
    "conversationId": "d6993a6a-84c6-4c36-8812-5d181ae025cd",
    "duplicate": true
  }
}
TranslatedErrorDto

Stable error envelope emitted by the global HTTP exception boundary. Domain-specific machine data, when present, is nested under details.

statusCodeRequired

HTTP status code repeated from the response.

integer
Full definition
{
  "type": "integer",
  "description": "HTTP status code repeated from the response.",
  "example": 400
}
errorRequired

Translation key for the HTTP category, such as errors:http.conflict. The specific cause is identified by code and translationKey.

string
Full definition
{
  "type": "string",
  "description": "Translation key for the HTTP category, such as errors:http.conflict. The specific cause is identified by code and translationKey.",
  "example": "errors.request.invalid"
}
codeRequired

Stable machine-readable domain code, or an HTTP_* fallback when no domain code is provided. Branch on this field and the HTTP status; localized wording never controls retries or business decisions.

string
Full definition
{
  "type": "string",
  "example": "HTTP_BAD_REQUEST",
  "description": "Stable machine-readable domain code, or an HTTP_* fallback when no domain code is provided. Branch on this field and the HTTP status; localized wording never controls retries or business decisions."
}
messageRequired

Translation key, identical to translationKey. The API does not return localized display text. Resolve the key and translationValues in the consuming application.

string
Full definition
{
  "type": "string",
  "example": "errors:http.badRequest",
  "description": "Translation key, identical to translationKey. The API does not return localized display text. Resolve the key and translationValues in the consuming application."
}
translationKeyRequired

Canonical translation key, identical to message. Status-specific errors:http.* keys cover unspecified failures. Public keys and EN/RU explanations are listed in Developers; unknown keys require a localized client fallback.

string
Full definition
{
  "type": "string",
  "example": "errors:http.badRequest",
  "description": "Canonical translation key, identical to message. Status-specific errors:http.* keys cover unspecified failures. Public keys and EN/RU explanations are listed in Developers; unknown keys require a localized client fallback."
}
translationValuesOptional

Optional scalar values for placeholders in the translation. Treat values as data, escape them when rendering, and never use them as translation options.

object
Full definition
{
  "type": "object",
  "additionalProperties": {
    "oneOf": [
      {
        "type": "string",
        "example": "example"
      },
      {
        "type": "number",
        "example": 0
      },
      {
        "type": "boolean",
        "example": true
      }
    ],
    "example": "example"
  },
  "description": "Optional scalar values for placeholders in the translation. Treat values as data, escape them when rendering, and never use them as translation options.",
  "example": {
    "exampleKey": "example"
  }
}
validationErrorsOptional

Field validation failures with translation keys and stable validator codes. Submitted values and raw validator text are not included.

array
Full definition
{
  "description": "Field validation failures with translation keys and stable validator codes. Submitted values and raw validator text are not included.",
  "type": "array",
  "items": {
    "$ref": "#/components/schemas/ValidationErrorDto"
  },
  "example": [
    {
      "field": "email",
      "translationKey": "validation:isEmail",
      "code": "isEmail",
      "message": "validation:isEmail"
    }
  ]
}
detailsOptional

Optional domain-specific blocker or validation details

oneOf
Full definition
{
  "description": "Optional domain-specific blocker or validation details",
  "oneOf": [
    {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/JsonValue"
      },
      "example": [
        "example"
      ]
    },
    {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/components/schemas/JsonValue"
      },
      "example": {
        "exampleKey": "example"
      }
    }
  ],
  "example": [
    "example"
  ]
}
Full definition
{
  "type": "object",
  "properties": {
    "statusCode": {
      "type": "integer",
      "description": "HTTP status code repeated from the response.",
      "example": 400
    },
    "error": {
      "type": "string",
      "description": "Translation key for the HTTP category, such as errors:http.conflict. The specific cause is identified by code and translationKey.",
      "example": "errors.request.invalid"
    },
    "code": {
      "type": "string",
      "example": "HTTP_BAD_REQUEST",
      "description": "Stable machine-readable domain code, or an HTTP_* fallback when no domain code is provided. Branch on this field and the HTTP status; localized wording never controls retries or business decisions."
    },
    "message": {
      "type": "string",
      "example": "errors:http.badRequest",
      "description": "Translation key, identical to translationKey. The API does not return localized display text. Resolve the key and translationValues in the consuming application."
    },
    "translationKey": {
      "type": "string",
      "example": "errors:http.badRequest",
      "description": "Canonical translation key, identical to message. Status-specific errors:http.* keys cover unspecified failures. Public keys and EN/RU explanations are listed in Developers; unknown keys require a localized client fallback."
    },
    "translationValues": {
      "type": "object",
      "additionalProperties": {
        "oneOf": [
          {
            "type": "string",
            "example": "example"
          },
          {
            "type": "number",
            "example": 0
          },
          {
            "type": "boolean",
            "example": true
          }
        ],
        "example": "example"
      },
      "description": "Optional scalar values for placeholders in the translation. Treat values as data, escape them when rendering, and never use them as translation options.",
      "example": {
        "exampleKey": "example"
      }
    },
    "validationErrors": {
      "description": "Field validation failures with translation keys and stable validator codes. Submitted values and raw validator text are not included.",
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/ValidationErrorDto"
      },
      "example": [
        {
          "field": "email",
          "translationKey": "validation:isEmail",
          "code": "isEmail",
          "message": "validation:isEmail"
        }
      ]
    },
    "details": {
      "description": "Optional domain-specific blocker or validation details",
      "oneOf": [
        {
          "type": "array",
          "items": {
            "$ref": "#/components/schemas/JsonValue"
          },
          "example": [
            "example"
          ]
        },
        {
          "type": "object",
          "additionalProperties": {
            "$ref": "#/components/schemas/JsonValue"
          },
          "example": {
            "exampleKey": "example"
          }
        }
      ],
      "example": [
        "example"
      ]
    }
  },
  "required": [
    "statusCode",
    "error",
    "code",
    "message",
    "translationKey"
  ],
  "description": "Stable error envelope emitted by the global HTTP exception boundary. Domain-specific machine data, when present, is nested under details.",
  "example": {
    "statusCode": 400,
    "error": "errors:http.badRequest",
    "code": "HTTP_BAD_REQUEST",
    "message": "errors:http.badRequest",
    "translationKey": "errors:http.badRequest"
  }
}
ValidationErrorDto

Field validation failure with a field path, stable validator code and a translation key. Human-readable text belongs to the consuming application.

fieldRequired

Public field path. Nested properties and array indices are separated by dots.

string
Full definition
{
  "type": "string",
  "example": "email",
  "description": "Public field path. Nested properties and array indices are separated by dots."
}
translationKeyRequired

Translation key for this validator, identical to message. Resolve it using a client dictionary; see the public Developers error catalog.

string
Full definition
{
  "type": "string",
  "example": "validation:isEmail",
  "description": "Translation key for this validator, identical to message. Resolve it using a client dictionary; see the public Developers error catalog."
}
codeRequired

Stable validator identifier for this field failure. Custom validators may define additional identifiers.

string
Full definition
{
  "type": "string",
  "example": "isEmail",
  "description": "Stable validator identifier for this field failure. Custom validators may define additional identifiers."
}
messageRequired

Translation key describing this field validation failure, identical to translationKey. Submitted values and validator prose are not included.

string
Full definition
{
  "type": "string",
  "example": "validation:isEmail",
  "description": "Translation key describing this field validation failure, identical to translationKey. Submitted values and validator prose are not included."
}
translationValuesOptional

Optional scalar values for placeholders in the translation. Treat values as data, escape them when rendering, and never use them as translation options.

object
Full definition
{
  "type": "object",
  "additionalProperties": {
    "oneOf": [
      {
        "type": "string",
        "example": "example"
      },
      {
        "type": "number",
        "example": 0
      },
      {
        "type": "boolean",
        "example": true
      }
    ],
    "example": "example"
  },
  "description": "Optional scalar values for placeholders in the translation. Treat values as data, escape them when rendering, and never use them as translation options.",
  "example": {
    "exampleKey": "example"
  }
}
Full definition
{
  "type": "object",
  "properties": {
    "field": {
      "type": "string",
      "example": "email",
      "description": "Public field path. Nested properties and array indices are separated by dots."
    },
    "translationKey": {
      "type": "string",
      "example": "validation:isEmail",
      "description": "Translation key for this validator, identical to message. Resolve it using a client dictionary; see the public Developers error catalog."
    },
    "code": {
      "type": "string",
      "example": "isEmail",
      "description": "Stable validator identifier for this field failure. Custom validators may define additional identifiers."
    },
    "message": {
      "type": "string",
      "example": "validation:isEmail",
      "description": "Translation key describing this field validation failure, identical to translationKey. Submitted values and validator prose are not included."
    },
    "translationValues": {
      "type": "object",
      "additionalProperties": {
        "oneOf": [
          {
            "type": "string",
            "example": "example"
          },
          {
            "type": "number",
            "example": 0
          },
          {
            "type": "boolean",
            "example": true
          }
        ],
        "example": "example"
      },
      "description": "Optional scalar values for placeholders in the translation. Treat values as data, escape them when rendering, and never use them as translation options.",
      "example": {
        "exampleKey": "example"
      }
    }
  },
  "required": [
    "field",
    "translationKey",
    "code",
    "message"
  ],
  "description": "Field validation failure with a field path, stable validator code and a translation key. Human-readable text belongs to the consuming application.",
  "example": {
    "field": "email",
    "translationKey": "validation:isEmail",
    "code": "isEmail",
    "message": "validation:isEmail"
  }
}
JsonValue

Recursively JSON-safe value used only where the owning contract intentionally allows free-form structured data.

Full definition
{
  "oneOf": [
    {
      "type": "string",
      "nullable": true,
      "example": "example"
    },
    {
      "type": "number",
      "example": 0
    },
    {
      "type": "boolean",
      "example": true
    },
    {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/JsonValue"
      },
      "example": [
        "example"
      ]
    },
    {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/components/schemas/JsonValue"
      },
      "example": {
        "exampleKey": "example"
      }
    }
  ],
  "description": "Recursively JSON-safe value used only where the owning contract intentionally allows free-form structured data.",
  "example": "example"
}

Hallify uses essential cookies and optional analytics.

Essential cookies keep sign-in, locale, and theme preferences working. Analytics is off until you choose to allow it.