This guide walks you through the full EP enforcement chain in 7 steps. By the end, you will have created a policy-bound handshake, verified mutual identity, issued an accountable signoff challenge, and consumed the authorization exactly once.
Time: ~30 minutes. Prerequisites: An EP API key (request access).
A handshake binds actor identity, authority, policy, exact action context, nonce, and expiry into a pre-action authorization flow.
POST /api/handshake
Authorization: Bearer ep_live_...
{
"mode": "mutual",
"policy_id": "your-policy-uuid",
"parties": [
{ "role": "initiator", "entity_ref": "your-entity-id" },
{ "role": "responder", "entity_ref": "counterparty-id" }
],
"action_type": "beneficiary_change",
"resource_ref": "acct-7291-usd",
"payload": {
"beneficiary_name": "Meridian Logistics Ltd",
"account_number": "****4821",
"routing": "SWIFT:MLOGUS33",
"effective_date": "2026-04-07"
}
}
handshake_id, binding (with binding_hash, payload_hash, nonce), action_hash, policy_hash. Save these for later steps.Each party presents their identity claims. The initiator presents with their own API key.
POST /api/handshake/{handshake_id}/present
Authorization: Bearer ep_live_initiator_key
{
"party_role": "initiator",
"presentation_type": "self_asserted",
"claims": { "name": "Jane Smith", "role": "Payments Operator" },
"disclosure_mode": "full"
}
The responder presents with their own API key. In mutual mode, both parties must present.
POST /api/handshake/{handshake_id}/present
Authorization: Bearer ep_live_responder_key
{
"party_role": "responder",
"presentation_type": "self_asserted",
"claims": { "name": "David Chen", "role": "Treasury Manager" },
"disclosure_mode": "full"
}
Pass the hashes from Step 1 so EP can verify binding integrity.
POST /api/handshake/{handshake_id}/verify
Authorization: Bearer ep_live_initiator_key
{
"payload_hash": "from step 1 binding",
"nonce": "from step 1 binding",
"action_hash": "from step 1",
"policy_hash": "from step 1"
}
outcome: "accepted" if both parties presented valid claims under the policy. Returns "rejected" with reason_codes if not.When policy requires human accountability, issue a challenge to a named responsible person.
POST /api/signoff/challenge
Authorization: Bearer ep_live_initiator_key
{
"handshakeId": "from step 1",
"accountableActorRef": "your-entity-id",
"bindingHash": "from step 1 binding",
"signoffPolicyId": "your-policy-uuid",
"requiredAssurance": "high",
"allowedMethods": ["platform_authenticator"],
"expiresAt": "2026-03-29T12:00:00Z"
}
challenge_id. The accountable actor must now attest.The named human confirms they reviewed and approve the exact action.
POST /api/signoff/{challenge_id}/attest
Authorization: Bearer ep_live_accountable_key
{
"humanEntityRef": "your-entity-id",
"authMethod": "platform_authenticator",
"assuranceLevel": "high",
"channel": "web",
"attestationHash": "sha256:your-attestation-hash"
}
signoff_id. The action is now approved and ready to consume.Consume the authorization exactly once. This is irreversible -- the signoff cannot be reused.
POST /api/signoff/{signoff_id}/consume
Authorization: Bearer ep_live_accountable_key
{
"executionRef": "your-execution-reference"
}
consumption_id and consumed_at. The action may now proceed. Any attempt to reuse this signoff will return 409 ALREADY_CONSUMED.By completing these 7 steps, you enforced:
Read the full protocol spec | Explore EP Cloud | Government use cases | Financial use cases | GitHub