---
title: "Submit signatures for an association."
method: POST
path: "/v1/associations/{id}/corroborate"
tags: ["Associations"]
---

# Submit signatures for an association.

`POST /v1/associations/{id}/corroborate`

## Request

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

Checks a signature produced by a key corresponding to the address, and on a match records the pair as observed to be operated together. That is the limit of what a signature establishes: a key can be held by somebody other than the party it is associated with, so this states nothing about who holds it, about title, or about identity. A signature that does not match leaves the record exactly where it was.

## Path parameters

- `id` string, required

## Request body

- union: Either one signature over an issued challenge, or both sides' own signed accounts. No other route reaches CORROBORATED.
  - object
    - `method` 'CHALLENGE', required
    - `nonce` string, required
    - `signature` string, required
  - object
    - `method` 'BOTH_PARTIES', required
    - `observed_at` string, date-time, required
    - `signatures` object[], required
      - `address` string, required
      - `signature` string, required

## Response `200`

The corroborated association.

- 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.
- `404`: No such resource.
- `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)
