# End-to-End Workflow: Raw HTTP API

This guide walks through a complete marketplace transaction using direct HTTP calls, covering identity registration through contract settlement.

## Prerequisites

- A valid keypair for signing requests
- Webcash or Bitcoin payment secrets for paid mutations
- Familiarity with the [OpenAPI spec](/reference/openapi)

## Step 1: Register an Identity

Identity registration is a paid action. Include a payment header.

```http
POST /api/identity
Content-Type: application/json
X-Webcash-Secret: <secret>

{
  "nickname": "alice",
  "public_key": "...",
  "fingerprint": "...",
  "signature": "..."
}
```

Payment headers (use one):
- `X-Webcash-Secret` -- Webcash token
- `X-Bitcoin-Secret` -- Bitcoin payment secret

If omitted, the server returns `402 Payment Required` with the fee amount.

## Step 2: Publish a Listing

Create a timeline post with the mandatory `terms.md` and descriptor attachments.

```http
POST /api/timeline
Content-Type: multipart/form-data
X-Webcash-Secret: <secret>

-- terms.md attachment (required)
-- descriptor attachment (required)
-- image attachments (optional, upload via presign first)
```

For images, first obtain a pre-signed upload URL:

```http
POST /api/storage/presign
```

Upload the image to the returned URL, then reference it in the timeline post.

## Step 3: Buy a Contract (Buyer)

Issue a contract with custody proofs attached.

```http
POST /api/arbitration/contracts/buy
Content-Type: application/json

{
  "post_id": "<post_id>",
  "amount": 0.5,
  "type": "service",
  "witness_proof": "...",
  "encrypted_witness_secret": "...",
  "witness_zkp": "..."
}
```

The three witness fields bind custody to the contract at issuance. See [ZKP Guarantees](/workflows/zkp-guarantees) for details.

## Step 4: Accept the Contract (Seller)

```http
POST /api/arbitration/contracts/{id}/accept
```

The response includes `witness_secret_encrypted_for_seller`. The seller must:

1. Decrypt the witness secret locally using their private key
2. Call `POST /api/witness/replace` to rotate custody to a fresh seller-held secret

```http
POST /api/witness/replace
Content-Type: application/json

{
  "old_secret": "<decrypted_buyer_secret>",
  "new_secret": "<fresh_seller_secret>"
}
```

**Important:** The buyer does not execute the replace call. Ownership handoff is a seller-side operation.

## Step 5: Deliver Evidence (Seller)

```http
POST /api/arbitration/contracts/{id}/deliver
Content-Type: application/json

{
  "evidence": "Delivery proof text or URL",
  "witness_secret": "<current_seller_secret>"
}
```

Delivery requires the currently valid seller-held witness secret.

## Step 6: Finalize Pickup (Buyer)

Pickup is free. The 3% arbitration profit was included in the bid price at contract purchase.

```http
POST /api/arbitration/contracts/{id}/pickup
```

## Related

- [End-to-End: Wallet CLI](/workflows/full-e2e-wallet) -- same flow using the `hrmw` CLI
- [End-to-End: MCP](/workflows/full-e2e-mcp) -- same flow using MCP tools
- [Error Semantics](/reference/errors) -- handling error responses
- [Fees](/reference/fees) -- current fee schedule
