> ## Documentation Index
> Fetch the complete documentation index at: https://docs.akhdar-sa.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Use {baseUrl} for the environment-specific base URL provided to the partner integration team. Do not invent an API hostname.
> x-akhdar-* fields are publication provenance only. Do not treat them as partner integration instructions.

# Contributions

> Confirm a loyalty-points contribution after the partner has deducted the customer's points.

<Warning>
  Confirm a loyalty-points contribution only after the partner has successfully deducted the customer's points.
</Warning>

## Contribution identities

Each identity has a distinct purpose:

* `Idempotency-Key` is the transport request-idempotency header. The same header with the same canonical payload returns the original result. Conflicting immutable request data returns `idempotency_conflict`.
* `partner_event_id` is the partner-supplied contribution uniqueness and recovery key. The same value with the same immutable request data returns the original contribution. Conflicting immutable request data returns `partner_event_conflict`.
* `partner_order_ref` is a stable, non-PII order correlation. Only one confirmed contribution is allowed per partner, environment, and order. A conflict returns `partner_order_conflict`.

## Confirm a contribution

Send `POST {baseUrl}/v1/impact-transactions` with `X-API-Key`, `Idempotency-Key`, and `Content-Type: application/json`.

Without an emissions estimate:

```json theme={null}
{
  "partner_event_id": "evt_contrib_01HZX5A1B2C3D4E5F6G7H8J9",
  "partner_order_ref": "ord_9f3c2a71",
  "points": 500,
  "opaque_customer_ref": "cust_ref_8a1b2c3d"
}
```

With an optional `calculation_id`:

```json theme={null}
{
  "partner_event_id": "evt_contrib_01HZX5A1B2C3D4E5F6G7H8J9",
  "partner_order_ref": "ord_9f3c2a71",
  "points": 500,
  "calculation_id": "calc_01HZX4K9M2Q8R7N6P5T4V3W2X1",
  "opaque_customer_ref": "cust_ref_8a1b2c3d"
}
```

An optional `calculation_id` must not invalidate an otherwise valid contribution.

`points` must be a positive whole number with a minimum value of `1`. An invalid shape returns `invalid_point_amount`, and no failed contribution record is persisted.

Successful confirmation returns HTTP `201`:

```json theme={null}
{
  "contribution": {
    "transaction_id": "txn_01HZX6M4N5P6Q7R8S9T0U1V2",
    "partner_event_id": "evt_contrib_01HZX5A1B2C3D4E5F6G7H8J9",
    "partner_order_ref": "ord_9f3c2a71",
    "status": "confirmed",
    "points": 500,
    "opaque_customer_ref": "cust_ref_8a1b2c3d",
    "contribution_rule_version": "CRV-v1.0.0",
    "point_conversion_version": "PCV-v1.0.0",
    "tree_cost_version": "TCV-v1.0.0",
    "expected_environmental_support": {
      "summary_en": "Support tree planting",
      "summary_ar": "ادعم زراعة الشجر"
    },
    "non_refundable": true,
    "environment": "sandbox",
    "created_at": "2026-08-03T12:05:00Z",
    "confirmed_at": "2026-08-03T12:05:00Z",
    "failed_at": null
  },
  "association": {
    "status": "not_requested"
  },
  "request": {
    "correlation_id": "corr_7c2e9b1a4d6f8e0c",
    "idempotency_key": "idem_01HZX5Z9Y8X7W6V5U4T3S2R1"
  }
}
```

## Contribution statuses

* `pending` is exceptional and non-final.
* `confirmed` is terminal and non-refundable.
* `failed` is terminal. Only then may the partner restore points.

`confirmed` and `failed` do not interchange.

## Recover a contribution

Use `partner_event_id` as the primary recovery key:

`GET {baseUrl}/v1/impact-transactions?partner_event_id=evt_contrib_01HZX5A1B2C3D4E5F6G7H8J9`

A secondary lookup is available by transaction ID:

`GET {baseUrl}/v1/impact-transactions/{transaction_id}`

See [Errors & Recovery](/errors-and-recovery) before restoring points after a timeout or unknown result.
