---
title: "Apply Proposal Route"
method: POST
path: "/internal/marketing-preset-proposals/{proposal_id}/apply"
tags: ["internal"]
---

# Apply Proposal Route

`POST /internal/marketing-preset-proposals/{proposal_id}/apply`

## Request

- Base URL: `https://api.kobaltlabs.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.kobaltlabs.com/internal/marketing-preset-proposals/{proposal_id}/apply`
- Auth: none declared

Create or edit the named product lines. The one path that writes a customer's config.

All or nothing: the whole submit is one transaction, so a refusal on the fourth row leaves the
customer exactly as the reviewer found them rather than four-fifths configured.

## Path parameters

- `proposal_id` string, uuid, required

## Request body

- ProposalApply: Exactly the rows the operator means to write, named from the page they are looking at. Naming them — rather than applying whatever the row says is approved — is what catches a page whose state was never saved, or was saved over by someone else: a key that isn't approved in the stored proposal is refused with a message saying so, instead of quietly writing a different set of product lines than the one on screen.
  - `keys` string[], required
  - `expected_revision` integer, required

## Response `200`

Successful Response

- AppliedProductLine[]
  - `key` string, required
  - `operation` 'create' | 'update', required: Whether an item creates a product line or edits one that exists.
  - `preset_id` string, uuid, required
  - `name` string, required

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/kobaltlabs/apis/fastapi.md) - [All operations](https://skmtc.dev/kobaltlabs/apis/fastapi/llms.txt) - [OpenAPI document](https://skmtc.dev/kobaltlabs/apis/fastapi/revisions/8587332d5e43?raw)
