# Programs

> Programs, pay, applications and agreements.

Source: https://www.onlucra.com/docs/api-programs

A program is a brief with pay terms. Creators join it through an **application**, [submit work](https://www.onlucra.com/docs/api-submissions), and get paid on approval or on how their work performs.

## Create a program

A program needs a `name`, a `type`, a `visibility` and its `pay`. This one pays $8 per 1,000 views on creators' posts, up to $500 each:

```json
{
  "name": "Spring launch",
  "type": "organic",
  "visibility": "network",
  "brief": "Show the jacket on a real trail run.",
  "pay": {
    "rules": [{ "per": "view", "amount": 800, "unit": 1000 }],
    "cap": 50000,
    "schedule": { "after": "measurement", "days": 7 }
  },
  "promoted": { "products": ["prod_04bst9MGXqblfqHhbR1iGGL"] },
  "agreements": ["agr_0HxY6vD1bN4tK8qLm2Rz9sW"]
}
```

- `type` is `organic` (paid on creators' own posts) or `paid_ads` (paid on ads made from their work).
- `visibility` is `invite` (only creators you add) or `network` (any creator can apply).
- `promoted.products` are the products creators can request samples of.
- `agreements` are the [agreements](#agreements) creators accept by joining.

The brand needs a payment method first, or you get `409 requirement_payment_method`.

`PATCH /v1/programs/:id` changes any of these. Every change in one request applies together, or none does. Set `status` to `paused`, `open` or `archived`.

## Pay

Each type pays per result in its own way:

| Type       | Paid per result                               | When                         |
| ---------- | --------------------------------------------- | ---------------------------- |
| `paid_ads` | A percent of ad spend or revenue, or per lead | As results come in           |
| `organic`  | Per 1,000 views, or per post                  | After a 1–30 day measurement |

On top of that, add flat pay per approved submission, per install, per click, or per [conversion](https://www.onlucra.com/docs/api-attribution#pay-per-conversion) on the brand's site, all under a `cap`. The full `pay` object is described in [Payments](https://www.onlucra.com/docs/api-payments#pay). Pay that could never be paid as set is refused with [`422 invalid_pay`](https://www.onlucra.com/docs/api-payments#pay-that-cant-be-paid).

Changing a program's pay creates a new version. Creators already in the program move to it on their next action there. To set one creator's pay, send `pay` on `PATCH /v1/applications/:id`.

## Applications

An application is a creator's place in a program. There are two ways in:

- **A brand adds a creator** with `{ "program", "creator" }`. They join approved and are notified.
- **A creator applies** to a `network` program with `{ "program" }`, acting as themselves.

```ts
await lucra.applications.create({
  body: { program: "prog_00lhuAJjQgdtNt5WnqTBc95", creator: "crtr_026UYfiw1Y6OvUpuKWiOpeL" },
})
```

Review an application with `PATCH /v1/applications/:id` and `status`: `approved`, `rejected`, or `pending` to reopen it.

Applying or joining is how a creator accepts the program's `agreements`; there's no separate signing step. Show the agreements under your button, like "By applying you agree to …". A creator a brand added still has to accept while `agreementsRequired` is `true`: they do it with `PATCH /v1/applications/:id` and `{ "status": "approved" }`.

## Agreements

Publish a PDF ([uploaded](https://www.onlucra.com/docs/api-files) with `purpose=agreement`) with `POST /v1/agreements`, then list it in a program's `agreements`. `GET /v1/agreements/acceptances` lists who accepted what.

## Posts

`GET /v1/posts` lists the creators' posts your organic programs pay for, with their views and earnings.

## Endpoints

- `GET /v1/applications` (read, SDK `lucra.applications.list`): List applications
- `GET /v1/applications/:id` (read, SDK `lucra.applications.retrieve`): Get an application
- `POST /v1/applications` (write, SDK `lucra.applications.create`): Invite a creator to a program, or apply as one
- `PATCH /v1/applications/:id` (write, SDK `lucra.applications.update`): Approve, reject or reopen an application, or set the creator's pay; as the creator, withdraw it or accept an invitation (approved)
- `GET /v1/agreements/acceptances` (read, SDK `lucra.agreements.acceptances.list`): List creators' acceptances of your agreements; as a creator, the ones you accepted and the ones waiting on you
- `GET /v1/agreements` (read, SDK `lucra.agreements.list`): List agreements
- `GET /v1/agreements/:id` (read, SDK `lucra.agreements.retrieve`): Get an agreement
- `GET /v1/agreements/:id/versions` (read, SDK `lucra.agreements.versions.list`): List an agreement's versions, newest first
- `GET /v1/agreements/:id/versions/:number` (read, SDK `lucra.agreements.versions.retrieve`): Get a version of an agreement by its number
- `POST /v1/agreements` (write, SDK `lucra.agreements.create`): Publish an agreement
- `POST /v1/agreements/:id/versions` (write, SDK `lucra.agreements.versions.create`): Publish a new version of an agreement
- `PATCH /v1/agreements/:id` (write, SDK `lucra.agreements.update`): Change where an agreement is required, or archive it
- `GET /v1/posts` (read, SDK `lucra.posts.list`): List creators' posts in organic programs
- `GET /v1/posts/:id` (read, SDK `lucra.posts.retrieve`): Get a post with its claim evidence
- `PATCH /v1/posts/:id` (write, SDK `lucra.posts.update`): Tag or archive a post
- `GET /v1/programs` (read, SDK `lucra.programs.list`): List programs: your own (archived ones only with status=archived), or with scope=network the open programs on the Lucra Network
- `GET /v1/programs/:id` (read, SDK `lucra.programs.retrieve`): Get a program
- `POST /v1/programs` (write, SDK `lucra.programs.create`): Create a program
- `PATCH /v1/programs/:id` (write, SDK `lucra.programs.update`): Update a program; every change in one request applies together, or none does
