> For the complete documentation index, see [llms.txt](https://docs.vomevolunteer.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.vomevolunteer.com/resources/opportunities/write-operations.md).

# Write Operations

Opportunities can be created, updated and assigned in bulk.

* **Create opportunities** adds new opportunities to a category.
* **Update opportunities** changes existing ones, matched by ID.
* **Upsert opportunities** does both in one call.
* **Assign users to opportunities** approves people onto opportunities that already exist.

#### What you need before you start

An opportunity refers to several other records by ID. All of them are listable:

| To set                     | You need       | Where to find it                       |
| -------------------------- | -------------- | -------------------------------------- |
| The category it belongs to | `category_id`  | [Categories](/resources/categories.md) |
| Coordinators and watchers  | admin IDs      | [Admins](/resources/admins.md)         |
| Tags                       | tag references | Opportunity Tags                       |
| Site links                 | site IDs       | Sites                                  |

#### What creating an opportunity does not set

These keep their Vome defaults and are not configurable here yet:

* qualification requirements: age, skills, languages and certifications
* the recurrence pattern behind a recurring commitment, although `commitment_type` can be set
* the cover image, which is an upload

Nothing is switched off by using the API; those settings simply stay at their defaults until an admin changes them in Vome.

#### Response shape

Every write endpoint answers with the same shape, where `errors` is keyed by the position of the entry in your request, starting at `1`.

```json
{
  "success": true,
  "processed": 1,
  "opportunities": [
    {
      "id": "2f56f3ef-08f5-4e5a-bf5b-76ca8fc4d5f1",
      "title": "Weekend Mentor",
      "category_id": "d610ab31-e480-4ef1-9e35-94f94ebacde9",
      "published": true
    }
  ],
  "errors": {}
}
```

By default nothing is written unless every entry is valid, and the response is `400`. Set `allow_partial` to `true` to write the valid entries and have the rest reported back. A request may carry at most 500 opportunities.
