> ## Documentation Index
> Fetch the complete documentation index at: https://mam-api.exuratech.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Registration and callback contract for completed allocation terminations.

| Method | Path | Response |
| - | - | - |
| `POST` | `/api/v1/mam/webhooks` | `201` with the destination and one-time-view `signing_secret`. |

## Registration

**name** `string` *required*

Stable consumer name, with a maximum of 120 characters.

**url** `string` *required*

HTTPS URL that will receive notifications.

Only one destination is supported for this service. A second registration returns `409`. Registration applies to future events only.

## Public event

`mam.allocation.terminated` reports an allocation that has already reached its final terminated state.

| `reason` | Meaning | Related fields |
| - | - | - |
| `USER_UNSUBSCRIBE` | Manual unsubscription requested by a user or CRM workflow. | `triggered_by` is `USER`. |
| `EQUITY_STOP` | Automatic unsubscription after the configured equity stop was reached. | `triggered_by` is `SYSTEM`; `stop_loss_value` and `trigger_equity` contain the stop context when available. |

## Callback payload

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "event_id": "8b9f1de6-2d11-5465-acc6-6ec7f6a32a28",
  "type": "mam.allocation.terminated",
  "version": 1,
  "occurred_at": "2026-07-28T00:19:05.020369Z",
  "data": {
    "allocation_id": 64,
    "reason": "EQUITY_STOP",
    "triggered_by": "SYSTEM",
    "status": "CANCELLED",
    "leader_account_id": 31,
    "leader_login": "146493",
    "follower_account_id": 42,
    "follower_login": "146537",
    "unsubscribe_policy": "CLOSE_ON_UNSUBSCRIBE",
    "allocation_mode": "EQUITY",
    "mode_parameter": "1.00000000",
    "equity_limit": null,
    "stop_loss_value": "800.00000000",
    "trigger_equity": "798.42000000",
    "closed_positions": 2,
    "failed_positions": 0,
    "performance_fee_due": "18.72",
    "performance_fee_charged": "18.72000000",
    "started_at": "2026-07-20T14:30:00Z",
    "terminated_at": "2026-07-28T00:19:05.020369Z"
  }
}
```

## Delivery headers

| Header | Contract |
| - | - |
| `X-MAM-Event-Id` | Matches the body `event_id`. |
| `X-MAM-Event-Type` | `mam.allocation.terminated`. |
| `X-MAM-Timestamp` | Unix timestamp in seconds used by the signature. |
| `X-MAM-Signature` | `sha256=<HMAC-SHA256 digest>`. |

## Delivery contract

* HMAC-SHA256 over `timestamp + "." + raw_body`.
* Verify the exact bytes before JSON parsing and use a constant-time comparison.
* Reject timestamps older or newer than five minutes.
* Retries may deliver the same `event_id` and payload more than once.
* Persist first, enforce a unique `event_id`, then respond with `2xx`.
* The signing secret cannot be retrieved after the registration response.

> [!NOTE]
>
> For a manual `CLOSE_ON_UNSUBSCRIBE`, the callback is emitted after position closing finishes and the allocation reaches `CANCELLED`, not while it is still `STOPPING`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.