Skip to documentationDocumentation
On this page

Create

Create a permanent static deposit address.

Creates a new static deposit address for the specified currency. Deposits to this address auto-create invoices. Static addresses are deposit rails for repeat deposits, not checkout sessions.

Idempotency: Idempotency-Key is required. A replay with the same key but different path parameters, query, or body returns 409 with code conflict. Exact request replays are idempotent and return the original address.

Usage notes#

Requires addresses:write. Save the returned address UUID against your customer ID. label is an annotation, not a unique external ID; this request has no external_id or metadata.

Use a supported currency/network pair and display address_tag whenever one is returned. Each deposit creates an invoice with source: static; read that invoice's static_address_id to correlate its invoice.* events. Creating an address is not itself a deposit or credit. See payment addresses.

POST/v1/addresses
curl
curl --request POST 'https://api.thehalfin.com/v1/addresses' \
  --header "X-API-Key: $HALFIN_API_KEY" \
  --header 'Idempotency-Key: createAddress-example-1001' \
  --header 'Content-Type: application/json' \
  --data '{
  "currency": "USDC",
  "network": "ethereum",
  "label": "Customer 1001"
}'

Authorization

  • X-API-KeystringRequired
    API key issued by the merchant dashboard. The key's environment (live/test) determines which data the caller can access. Permissions on the key control which endpoints are reachable.

    Example: $HALFIN_API_KEY

Header Parameters

  • Idempotency-KeystringRequired

    Persist a unique key before sending this operation. Retry an uncertain outcome with the same key and unchanged request; a new operation needs a new key.

    See idempotency and retries for replay, conflict, and key-release behavior.

    Full header contract

    Required for merchant POST requests that create invoices, addresses, payouts, or refunds. Use a unique key for each intended operation. The same key namespace is shared by all merchant operations within the same merchant and environment. Retry the original request with the same key and unchanged path, query, and body. JSON key ordering and insignificant whitespace are ignored; numeric literals and string values are preserved ("10" differs from "10.00"). Changing any field under a bound key returns 409 conflict. An executing request returns 409 in_flight. An exact retry returns the permanent original outcome with Idempotent-Replayed: true. Only Idempotency-Key-Released: true confirms that a refused attempt released the key. An unconfirmed release returns 503 service_unavailable without that header. Under uncertainty, retry the original request with the same key. The key is never echoed in response bodies. Keys contain 1–255 printable ASCII characters without spaces; a UUID is recommended.

    • Minimum length: 1
    • Maximum length: 255
    • Pattern: ^[\x21-\x7E]+$

    Example: createAddress-example-1001

Request Body

Required

application/json

  • currencystringRequired
    Cryptocurrency code for the static address.
    • Minimum length: 1
    • Maximum length: 20

    Example: string

  • networkstringRequired
    Blockchain network (e.g. bitcoin, ethereum, solana, tron). Required together with currency. An unknown pair returns `422 gate_unknown`; an omitted or empty member returns `400 validation_error`.
    • Minimum length: 1
    • Maximum length: 30

    Example: string

  • labelstringOptional
    Optional human-readable label.
    • Maximum length: 1000

    Example: string

Response Body

201 Static address created.

  • Idempotent-Replayed"true"Optional
    Present and true when returning the stored outcome of an earlier execution.

    Example: true

  • Idempotency-Key-Released"true"Optional
    Present and true after a proven no-effect refusal and confirmed release. This attempt bound nothing; a concurrent request may acquire the key.

    Example: true

application/json

  • dataobjectRequired
    • Unknown properties are rejected

    Example: {"id":"00000000-0000-0000-0000-000000000003","merchant_id":"00000000-0000-0000-0000-000000000002","currency":"USDC","network":"ethereum","environment":"live","address":"0x0000000000000000000000000000000000000001","address_tag":null,"label":"Customer 1001","total_received":"0","invoice_count":0,"created_at":"2026-09-14T10:00:00Z"}

    • idstringRequired
      Static address UUID.
      • Format: uuid

      Example: 00000000-0000-0000-0000-000000000001

    • merchant_idstring | nullRequired
      Owning merchant UUID.
      • Format: uuid

      Example: null

    • currencystringRequired
      Currency code.

      Example: string

    • networkstringRequired
      Blockchain network key (e.g. ethereum, tron, bitcoin).

      Example: string

    • environment"live" | "test"Required
      Environment.

      Example: live

    • addressstringRequired
      Blockchain deposit address.

      Example: string

    • address_tagstring | nullRequired
      Memo/tag for chains that require it.

      Example: null

    • labelstringRequired
      Human-readable label.

      Example: string

    • total_receivedstringRequired
      Decimal string of total deposits received.

      Example: 1

    • invoice_countintegerRequired
      Number of auto-created invoices.

      Example: 0

    • created_atstringRequired
      Creation timestamp.
      • Format: date-time

      Example: 2026-01-01T00:00:00Z

    • status"active" | "retired"Required
      `active`: the address takes deposits and may be shown to payers. `retired`: the address is no longer offered and must not be shown to payers; a deposit that still reaches it is recorded on its history as before. An address the platform retired is replaced by a fresh one (`replaced_by`) and is not listed among the merchant's addresses; it stays readable by id with its invoices.

      Example: active

    • replaced_bystring | nullRequired
      The static address that replaced this retired one, once it is issued; null otherwise.
      • Format: uuid

      Example: null

  • metaobjectRequired
    • Unknown properties are rejected

    Example: {"request_id":"00000000-0000-0000-0000-000000000001"}

    • request_idstringRequired
      Correlation identifier issued by the API, also returned in the X-Request-ID response header. Client-supplied X-Request-ID values are replaced.

      Example: string

201 response
{
  "data": {
    "id": "00000000-0000-0000-0000-000000000003",
    "merchant_id": "00000000-0000-0000-0000-000000000002",
    "currency": "USDC",
    "network": "ethereum",
    "environment": "live",
    "address": "0x0000000000000000000000000000000000000001",
    "address_tag": null,
    "label": "Customer 1001",
    "total_received": "0",
    "invoice_count": 0,
    "created_at": "2026-09-14T10:00:00Z"
  },
  "meta": {
    "request_id": "00000000-0000-0000-0000-000000000001"
  }
}

400 `validation_error`: The request format, parameters, headers, or field values are invalid.

  • Idempotent-Replayed"true"Optional
    Present and true when returning the stored outcome of an earlier execution.

    Example: true

  • Idempotency-Key-Released"true"Optional
    Present and true after a proven no-effect refusal and confirmed release. This attempt bound nothing; a concurrent request may acquire the key.

    Example: true

application/json

  • errorobjectRequired
    The error code and diagnostic message.
    • Unknown properties are rejected

    Example: {"code":"validation_error","message":"string","details":["string"]}

    • code"validation_error"Required
      `validation_error`: The request format, parameters, headers, or field values are invalid.

      Example: validation_error

    • messagestringRequired
      Human-readable description of the error.

      Example: string

    • detailsarray<string>Optional
      Optional structured context (validation errors, etc.).

      Example: ["string"]

  • metaobjectRequired
    • Unknown properties are rejected

    Example: {"request_id":"00000000-0000-0000-0000-000000000001"}

    • request_idstringRequired
      Correlation identifier issued by the API, also returned in the X-Request-ID response header. Client-supplied X-Request-ID values are replaced.

      Example: string

400 response
{
  "error": {
    "code": "validation_error",
    "message": "Request validation failed"
  },
  "meta": {
    "request_id": "00000000-0000-0000-0000-000000000001"
  }
}

401 `unauthorized`: A valid API key is required.

  • Idempotent-Replayed"true"Optional
    Present and true when returning the stored outcome of an earlier execution.

    Example: true

  • Idempotency-Key-Released"true"Optional
    Present and true after a proven no-effect refusal and confirmed release. This attempt bound nothing; a concurrent request may acquire the key.

    Example: true

application/json

  • errorobjectRequired
    The error code and diagnostic message.
    • Unknown properties are rejected

    Example: {"code":"unauthorized","message":"string","details":["string"]}

    • code"unauthorized"Required
      `unauthorized`: A valid API key is required.

      Example: unauthorized

    • messagestringRequired
      Human-readable description of the error.

      Example: string

    • detailsarray<string>Optional
      Optional structured context (validation errors, etc.).

      Example: ["string"]

  • metaobjectRequired
    • Unknown properties are rejected

    Example: {"request_id":"00000000-0000-0000-0000-000000000001"}

    • request_idstringRequired
      Correlation identifier issued by the API, also returned in the X-Request-ID response header. Client-supplied X-Request-ID values are replaced.

      Example: string

401 response
{
  "error": {
    "code": "unauthorized",
    "message": "Invalid API key"
  },
  "meta": {
    "request_id": "00000000-0000-0000-0000-000000000001"
  }
}

403 `forbidden`: The API key does not have permission for this operation. `api_key_ip_forbidden`: The request source address is not allowed by the API key.

  • Idempotent-Replayed"true"Optional
    Present and true when returning the stored outcome of an earlier execution.

    Example: true

  • Idempotency-Key-Released"true"Optional
    Present and true after a proven no-effect refusal and confirmed release. This attempt bound nothing; a concurrent request may acquire the key.

    Example: true

application/json

  • errorobjectRequired
    The error code and diagnostic message.
    • Unknown properties are rejected

    Example: {"code":"forbidden","message":"string","details":["string"]}

    • code"forbidden" | "api_key_ip_forbidden"Required
      `forbidden`: The API key does not have permission for this operation. `api_key_ip_forbidden`: The request source address is not allowed by the API key.

      Example: forbidden

    • messagestringRequired
      Human-readable description of the error.

      Example: string

    • detailsarray<string>Optional
      Optional structured context (validation errors, etc.).

      Example: ["string"]

  • metaobjectRequired
    • Unknown properties are rejected

    Example: {"request_id":"00000000-0000-0000-0000-000000000001"}

    • request_idstringRequired
      Correlation identifier issued by the API, also returned in the X-Request-ID response header. Client-supplied X-Request-ID values are replaced.

      Example: string

403 response
{
  "error": {
    "code": "forbidden",
    "message": "Permission denied"
  },
  "meta": {
    "request_id": "00000000-0000-0000-0000-000000000001"
  }
}

409 `conflict`: The idempotency key is bound to a different request, or this request conflicts with an existing resource. `in_flight`: A request with this idempotency key is still executing. Retry the original request with the same key.

  • Idempotent-Replayed"true"Optional
    Present and true when returning the stored outcome of an earlier execution.

    Example: true

  • Idempotency-Key-Released"true"Optional
    Present and true after a proven no-effect refusal and confirmed release. This attempt bound nothing; a concurrent request may acquire the key.

    Example: true

application/json

  • errorobjectRequired
    The error code and diagnostic message.
    • Unknown properties are rejected

    Example: {"code":"conflict","message":"string","details":["string"]}

    • code"conflict" | "in_flight"Required
      `conflict`: The idempotency key is bound to a different request, or this request conflicts with an existing resource. `in_flight`: A request with this idempotency key is still executing. Retry the original request with the same key.

      Example: conflict

    • messagestringRequired
      Human-readable description of the error.

      Example: string

    • detailsarray<string>Optional
      Optional structured context (validation errors, etc.).

      Example: ["string"]

  • metaobjectRequired
    • Unknown properties are rejected

    Example: {"request_id":"00000000-0000-0000-0000-000000000001"}

    • request_idstringRequired
      Correlation identifier issued by the API, also returned in the X-Request-ID response header. Client-supplied X-Request-ID values are replaced.

      Example: string

409 response
{
  "error": {
    "code": "conflict",
    "message": "Request conflicts with the existing state"
  },
  "meta": {
    "request_id": "00000000-0000-0000-0000-000000000001"
  }
}

422 `unprocessable_entity`: The requested address cannot be issued for these details. `gate_unknown`: The requested currency and network pair is unknown. `gate_not_enabled`: The currency and network pair is not enabled for this merchant in this environment.

  • Idempotent-Replayed"true"Optional
    Present and true when returning the stored outcome of an earlier execution.

    Example: true

  • Idempotency-Key-Released"true"Optional
    Present and true after a proven no-effect refusal and confirmed release. This attempt bound nothing; a concurrent request may acquire the key.

    Example: true

application/json

  • errorobjectRequired
    The error code and diagnostic message.
    • Unknown properties are rejected

    Example: {"code":"unprocessable_entity","message":"string","details":["string"]}

    • code"unprocessable_entity" | "gate_unknown" | "gate_not_enabled"Required
      `unprocessable_entity`: The requested address cannot be issued for these details. `gate_unknown`: The requested currency and network pair is unknown. `gate_not_enabled`: The currency and network pair is not enabled for this merchant in this environment.

      Example: unprocessable_entity

    • messagestringRequired
      Human-readable description of the error.

      Example: string

    • detailsarray<string>Optional
      Optional structured context (validation errors, etc.).

      Example: ["string"]

  • metaobjectRequired
    • Unknown properties are rejected

    Example: {"request_id":"00000000-0000-0000-0000-000000000001"}

    • request_idstringRequired
      Correlation identifier issued by the API, also returned in the X-Request-ID response header. Client-supplied X-Request-ID values are replaced.

      Example: string

422 response
{
  "error": {
    "code": "unprocessable_entity",
    "message": "The request cannot be processed in the current state"
  },
  "meta": {
    "request_id": "00000000-0000-0000-0000-000000000001"
  }
}

500 `internal_error`: The API could not complete the request. Contact support with the request ID if the error persists.

  • Idempotent-Replayed"true"Optional
    Present and true when returning the stored outcome of an earlier execution.

    Example: true

  • Idempotency-Key-Released"true"Optional
    Present and true after a proven no-effect refusal and confirmed release. This attempt bound nothing; a concurrent request may acquire the key.

    Example: true

application/json

  • errorobjectRequired
    The error code and diagnostic message.
    • Unknown properties are rejected

    Example: {"code":"internal_error","message":"string","details":["string"]}

    • code"internal_error"Required
      `internal_error`: The API could not complete the request. Contact support with the request ID if the error persists.

      Example: internal_error

    • messagestringRequired
      Human-readable description of the error.

      Example: string

    • detailsarray<string>Optional
      Optional structured context (validation errors, etc.).

      Example: ["string"]

  • metaobjectRequired
    • Unknown properties are rejected

    Example: {"request_id":"00000000-0000-0000-0000-000000000001"}

    • request_idstringRequired
      Correlation identifier issued by the API, also returned in the X-Request-ID response header. Client-supplied X-Request-ID values are replaced.

      Example: string

500 response
{
  "error": {
    "code": "internal_error",
    "message": "Internal server error"
  },
  "meta": {
    "request_id": "00000000-0000-0000-0000-000000000001"
  }
}

503 `service_unavailable`: The service is temporarily unavailable. If the outcome is uncertain, retry the original request with the same idempotency key.

  • Idempotency-Key-Released"true"Optional
    Present and true after a proven no-effect refusal and confirmed release. This attempt bound nothing; a concurrent request may acquire the key.

    Example: true

  • Idempotent-Replayed"true"Optional
    Present and true when returning the stored outcome of an earlier execution.

    Example: true

application/json

  • errorobjectRequired
    The error code and diagnostic message.
    • Unknown properties are rejected

    Example: {"code":"service_unavailable","message":"string","details":["string"]}

    • code"service_unavailable"Required
      `service_unavailable`: The service is temporarily unavailable. If the outcome is uncertain, retry the original request with the same idempotency key.

      Example: service_unavailable

    • messagestringRequired
      Human-readable description of the error.

      Example: string

    • detailsarray<string>Optional
      Optional structured context (validation errors, etc.).

      Example: ["string"]

  • metaobjectRequired
    • Unknown properties are rejected

    Example: {"request_id":"00000000-0000-0000-0000-000000000001"}

    • request_idstringRequired
      Correlation identifier issued by the API, also returned in the X-Request-ID response header. Client-supplied X-Request-ID values are replaced.

      Example: string

503 response
{
  "error": {
    "code": "service_unavailable",
    "message": "Service temporarily unavailable"
  },
  "meta": {
    "request_id": "00000000-0000-0000-0000-000000000001"
  }
}