> ## Documentation Index
> Fetch the complete documentation index at: https://docs.switchbord.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Compatibility Surface

> Charles-style legacy paths and staged aliases currently modeled by the API app.

# Compatibility Surface

This project currently carries two compatibility layers:

* staged aliases under `/compat/*` for local iteration
* Charles-style legacy paths for drop-in replacement testing

## Contact mutation

### Staged path

* `POST /compat/contact`

### Legacy path

* `PUT /api/v1beta/contact/`

### Notes

* request bodies preserve the Charles-style contact update shape
* `external_reference_id`, `source_type`, and `person_properties` remain first-class
* the legacy path returns `status` and `message` fields to match upstream expectations

## Journey trigger

### Staged path

* `POST /compat/journey-trigger/{legacyPath}`

### Legacy paths

* `POST /webhooks/v0/rest-trigger/organization/{organizationId}/flow/{flowId}/trigger/`
* `POST /webhooks/v0/rest-trigger/organization/{organizationId}/flow/{flowId}/trigger/{triggerId}/`

### Notes

* payloads remain phone-number centric
* arbitrary personalization keys are accepted and forwarded into the queued job payload
* the legacy path returns `status`, `message`, `triggerEventId`, and `outboxJobId`

## Partner-triggered webhooks

### Legacy path

* `POST /api/v0/webhooks/incoming/emarsys/custom_external_event`

### Notes

* both flattened and nested contact payload styles are normalized
* `event_name` is required and must not contain whitespace
* when configured, `EMARSYS_WEBHOOK_SECRET` is enforced through the `secret` query parameter
* successful responses return `status`, `message`, `webhookEventId`, and `outboxJobId`

## Migration posture

This layer is not meant to be the permanent architecture. It is the controlled boundary that lets Twenty CRM and Charles-era automations migrate without requiring simultaneous upstream rewrites.
