---
title: "Record that two addresses are observed to be operated together."
method: POST
path: "/v1/associations"
tags: ["Associations"]
---

# Record that two addresses are observed to be operated together.

`POST /v1/associations`

## Request

- Base URL: `https://api.fidren.net`
- URL: `https://api.fidren.net/v1/associations`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

Always recorded as an assertion, whatever the body says: the state and the provenance are not parameters. An assertion changes nothing served about either address and cannot until a signature is checked, which is what keeps naming somebody else's addresses from being an attack. Authenticated, so that every record has an author who can be asked about it. An assertion nobody corroborates is retracted rather than kept.

## Request body

- AssociationRequest
  - `address` string, required
  - `peer_address` string, required
  - `chain` string
  - `grounds` string, required: What was observed. Not a statement about who anybody is; such a statement is not published at any confidence.
  - `self_declared` boolean: Whether the caller is speaking about its own addresses. It changes the recorded provenance and nothing else: a self-declaration is inert until a signature arrives, exactly as a third-party assertion is.

## Response `201`

The recorded assertion.

- Association: An observation that two addresses are operated together, at a stated time and under a stated association version. It states nothing about who holds either key, and naming a real-world party is outside what Fidren publishes at any confidence.
  - `public_id` string, nullable, required: The stable, opaque identifier for this association, and the one to store. Accepted wherever an association is addressed. Null only on a legacy row that predates this field.
  - `id` integer, required: Deprecated legacy identifier. It is a global sequence, so the difference between two of them discloses roughly how much other traffic Fidren handled in between; it is retained only because removing it would break existing clients. Use `public_id`. It is not carried into the next API namespace.
  - `chain` string, required
  - `address` string, required
  - `peer_address` string, required
  - `provenance` 'SELF_DECLARED' | 'THIRD_PARTY' | 'PROVEN_CONTROL' | 'BOTH_PARTIES_SIGNED', required: How the record came to exist. It never substitutes for the ladder below: an assertion changes nothing served whoever made it.
  - `status` 'ASSERTED' | 'CORROBORATED' | 'CONTESTED' | 'CORRECTED' | 'RETRACTED', required: The state decides whether an assessment ever sees the record. Only CORROBORATED reaches it. CORRECTED and RETRACTED are terminal.
  - `confidence` 'LOW' | 'MEDIUM' | 'HIGH', required
  - `association_version` string, required: The association rules in force when the row was written. It moves on its own schedule, so a revision that widens association is visible as a revision.
  - `observed_at` string, date-time, required
  - `corroborated_at` string, date-time, nullable, required
  - `resolved_at` string, date-time, nullable, required
  - `expires_at` string, date-time, nullable, required: When an assertion that was never corroborated stops being left open and is retracted. Retraction stops future effect; it is not a finding that the record was wrong, and it deletes nothing.
  - `note` string: Plain-language statement of what this write changed and what it did not. Present on the responses to `POST /v1/associations` and `POST /v1/associations/{id}/corroborate`; absent from `GET /v1/associations/{id}`, which reports the record and no action. Prose for a human — its wording may change; do not parse it.

## Other responses

- `400`: The request was rejected by validation.
- `401`: No usable access path. Either a key was presented and is not valid, or no key was presented, the free allowance is spent, and x402 charging is off. A presented key never falls back to the free tier or to being charged.
- `403`: The API key is valid, but its organization is not currently permitted to make this request. Do not rotate the key: it is not the problem.
- `429`: Rate limit exceeded. Retry after the number of seconds in `Retry-After`.
- `503`: A required dependency is unavailable. Safe to retry.

---

[API](https://skmtc.dev/fidren/apis/fidren-decision-api.md) · [All operations](https://skmtc.dev/fidren/apis/fidren-decision-api/llms.txt) · [OpenAPI document](https://skmtc.dev/fidren/apis/fidren-decision-api/revisions/d4b4dafcb345?raw)
