---
title: "Redeem a paid Invoice Fix Report for an API key"
method: POST
path: "/v1/fix/claim"
tags: ["Billing"]
---

# Redeem a paid Invoice Fix Report for an API key

`POST /v1/fix/claim`

## Request

- Base URL: `https://api.attestwire.com`
- URL: `https://api.attestwire.com/v1/fix/claim`
- Auth: none required

The Invoice Fix Report is a one-time $99 purchase, not a subscription: there is nothing to cancel and nothing renews. It grants 30 days of starter on a newly minted key, the signed Validation Record for every run (add `?record=true` to POST /v1/validate), and a human review of the findings.

**THE REVIEW IS NOT AN ENDPOINT.** It is a person, and it starts when the buyer emails hello@attestwire.com quoting the transaction id. The 200 body below says so in `instructions`, because a buyer who never sends that email has received two thirds of what they paid for.

**The key is returned exactly once.** Only its SHA-256 hash is stored, so it cannot be re-sent or recovered by anyone — the same policy every key here is issued under. A second claim answers `409 already_claimed`.

After 30 days the key KEEPS WORKING and drops to the free tier: nothing is revoked and nothing is deleted, only the monthly allowance changes. GET /v1/usage publishes the date as `tier_expires` both before and after it passes.

## Request body

- object
  - `transaction_id` string, required: The Paddle transaction id from the receipt email, or from the URL checkout returned the buyer to. Not the subscription id and not the invoice number.

## Response `200`

Claimed. `key` is shown here and nowhere else, ever — store it before closing the connection.

- object
  - `key` string, required
  - `tier` 'free' | 'solo' | 'starter' | 'scale', required
  - `monthly_limit` integer, required
  - `created` string, date-time, required
  - `expires` string, date-time, required: When the tier lapses to free. The key itself never expires and is never deleted.
  - `days` integer, required
  - `transaction_id` string, required
  - `support_email` string, email, required
  - `instructions` string[], required: The full deliverable path, in order: store the key, validate with `?record=true` for the shareable Validation Record, and email for the human review. Written for a reader who has never seen the docs.
  - `warning` string, required

## Other responses

- `400`: The body is not a JSON object, or `transaction_id` is missing or does not look like a Paddle transaction id. Checked BEFORE the per-IP limiter, so a typo does not spend one of the day's attempts.
- `404`: That transaction id does not match a completed Fix Report purchase. DELIBERATELY THE SAME ANSWER for an unknown id, a payment that has not settled, and a transaction for something else: the route must not be usable to discover which transaction ids exist. Nothing was charged.
- `409`: Already redeemed. The key minted then was shown once and cannot be shown again by anybody here.
- `413`: The request body is over 1 MB. Nothing was read and nothing was charged.
- `429`: More than 10 claim attempts from this address today. A genuine claim needs one; the limit is deliberately mean because this is the only public route that mints a paid key.
- `500`: Unhandled fault while claiming the Fix Report. Never expected; the body carries no detail on purpose (a fault message can quote the offending value). Retry, and email hello@attestwire.com if it persists.
- `502`: The payment provider could not be reached to verify the purchase. Nothing was claimed and the Fix Report is untouched; retry shortly.
- `503`: The Fix Report is not configured on this deployment (no price id, or no Paddle API key to verify a purchase with).

---

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