# Create attribute

URL: https://docs.hanzo.ai/docs/openapi/affiliate/post-affiliate-attribute

> Records the first-touch edge every later commission is computed from: the caller's org was referred by the affiliate that owns this code.

`POST /v1/affiliate/attribute`

> [Affiliate →](https://docs.hanzo.ai/docs/openapi/affiliate) · [All API references →](https://docs.hanzo.ai/docs/openapi) · [Get started →](https://docs.hanzo.ai/docs/guides)

|               |                                               |
| ------------- | --------------------------------------------- |
| **Address**   | `https://api.hanzo.ai/v1/affiliate/attribute` |
| **Method**    | `POST`                                        |
| **Operation** | `post_affiliate_attribute`                    |
| **Auth**      | `Authorization: Bearer $HANZO_API_KEY`        |

Records the first-touch edge every later commission is computed
from: the caller's org was referred by the affiliate that owns this code.

The REFERRED org is the validated caller, never a field. A caller that could
name the referred org could attach itself to somebody else's revenue. The
affiliate is resolved from the code, and only an APPROVED affiliate's code
resolves.

FIRST TOUCH WINS, set once: one affiliate per referred org, so a re-post
answers the existing edge with `created:false` rather than moving the
attribution. Self-attribution is refused, and so is a code that would make a
cycle in the upline chain. An unknown code is a 404, deliberately: an
affiliate code IS a public shareable link, so whether one is real is public by
design, and the caller legitimately needs to know its link resolved.

A user-level mirror of the edge is written best-effort; a conflict there never
fails the org attribution, which is the money-bearing one.

## Request

1 field, body `application/json` (required).

| Field  | In   | Type   | Required | Description                                               |
| ------ | ---- | ------ | -------- | --------------------------------------------------------- |
| `code` | body | string | —        | Code is the affiliate code the referred org arrived with. |

## Response

| Status    | Body                  | Meaning |
| --------- | --------------------- | ------- |
| `200`     | affiliate.attribution | ok      |
| `201`     | affiliate.attribution | created |
| `default` | problem-details       | refused |

`200` body — 4 fields.

| Field       | In   | Type            | Always | Description                                                                       |
| ----------- | ---- | --------------- | ------ | --------------------------------------------------------------------------------- |
| `code`      | body | string          | —      | Code is the affiliate code the edge was recorded under, normalized to lower case. |
| `created`   | body | boolean         | —      | Created says whether THIS call made the edge.                                     |
| `createdAt` | body | integer (int64) | —      | CreatedAt is when the edge was FIRST recorded, Unix seconds UTC.                  |
| `id`        | body | string          | —      | ID is the attribution edge's server-minted handle, "afr\_"-prefixed.              |

Failure carries the platform error shape — see [Errors](https://docs.hanzo.ai/docs/errors).

## Examples

**CLI**

```bash
hanzo affiliate attribute
```

**SDK**

**.ts**

```ts
import { Configuration, AffiliateApi } from 'hanzoai';

const api = new AffiliateApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postAffiliateAttribute({ code: "<code>" });
```

**.py**

```python
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import AffiliateApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = AffiliateApi(client).post_affiliate_attribute(code="<code>")
```

**.go**

```go
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.AffiliateAPI.PostAffiliateAttribute(context.Background()).Execute()
if err != nil {
	return err
}
```

**.rs**

```rust
use hanzo_client::apis::{configuration::Configuration, affiliate_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = affiliate_api::post_affiliate_attribute(&cfg, Default::default()).await?;
```

**.java**

```java
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.AffiliateApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new AffiliateApi(client).postAffiliateAttribute();
```

**HTTP**

```bash
curl -X POST https://api.hanzo.ai/v1/affiliate/attribute \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "code": "<code>"
     }'
```

**MCP**

MCP reaches **affiliate** through the `affiliate` tool, which names its 10 operations with its own verbs — this one among them, under a name only MCP declares. `describe` explains any of them:

```bash
curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "describe",
         "arguments": {
           "op": "list_affiliates"
         }
       }
     }'
```

---

[Affiliate API](https://docs.hanzo.ai/docs/openapi/affiliate) · [All Hanzo APIs](https://docs.hanzo.ai/docs/openapi) · [Interactive reference](https://docs.hanzo.ai/docs/openapi/reference)
