# POST /api/v1/jobs

Reserve job from quote (quote owner)

Operation: `createJob`.

Reserve job from quote (quote owner)

Atomically holds budget, reserves machine, increments fence and queues start. Rejects expired quote (409 QUOTE_EXPIRED), changed manifest, unavailable or not admitted machine, or insufficient spendable funds (409 INSUFFICIENT_FUNDS) without partial holds. Replaying the same Idempotency-Key with the same body returns the original job, so a timed-out request is safe to retry; the same key with another body is 409 IDEMPOTENCY_CONFLICT and reserves nothing.

## Endpoint

`POST https://amplerun-api.spiry.org/api/v1/jobs`

## Authentication

Use the credential and scope required by this operation. For programmatic renter/host calls: `Authorization: Bearer $AMPLERUN_API_KEY`. A host-agent signature or other specialized proof is required where the description specifies it.

## Parameters

| Name | Location | Presence | Type | Description |
| --- | --- | --- | --- | --- |
| `Idempotency-Key` | header | Required | UUID | UUID scoped to authenticated principal, route and canonical request hash. |

## Request body

Required body. 

### `application/json`

| Field | Type | Presence | Description |
| --- | --- | --- | --- |
| `quote_id` | UUID | Required |  |
| `ssh_public_key` | string | Optional | One-line OpenSSH public key installed for the tenant user. Optional: without it the server installs a generated key whose private half it discards, so SSH is off for that rental (model rentals chat through /jobs/{id}/openai/v1). |

```json
{
  "type": "object",
  "additionalProperties": false,
  "required": [
    "quote_id"
  ],
  "properties": {
    "quote_id": {
      "$ref": "#/components/schemas/UUID"
    },
    "ssh_public_key": {
      "type": "string",
      "minLength": 1,
      "maxLength": 4096,
      "description": "One-line OpenSSH public key installed for the tenant user. Optional: without it the server installs a generated key whose private half it discards, so SSH is off for that rental (model rentals chat through /jobs/{id}/openai/v1)."
    }
  }
}
```

Contract example:

```json
{
  "quote_id": "0c1d2e3f-4a5b-4c6d-8e7f-8091a2b3c4d5",
  "ssh_public_key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGVxYW1wbGVrZXlfbm90X3JlYWw you@laptop"
}
```

## Responses

### `202`

Job reserved.

`application/json`
| Field | Type | Presence | Description |
| --- | --- | --- | --- |
| `job_id` | UUID | Required |  |
| `state` | schema | Required |  |

```json
{
  "type": "object",
  "required": [
    "job_id",
    "state"
  ],
  "properties": {
    "job_id": {
      "$ref": "#/components/schemas/UUID"
    },
    "state": {
      "const": "RESERVED"
    }
  }
}
```

### `default`

Error envelope. 401 unauthenticated, 403/404 forbidden, 409 conflict, 422 invalid input, 429 rate limited (code UNAVAILABLE, retryable:true, no Retry-After header), 503 unavailable money/provider state with retryable:true.

`application/json`
| Field | Type | Presence | Description |
| --- | --- | --- | --- |
| `error` | object | Required |  |

```json
{
  "$ref": "#/components/schemas/ErrorEnvelope"
}
```

## Static request outline

Replace path/query placeholders and provide the required JSON body, headers and credential from the sections above. This is a request outline, not a command that chooses an amount or starts a rental for you.

```sh
curl --request POST 'https://amplerun-api.spiry.org/api/v1/jobs' \
  --header "Authorization: Bearer $AMPLERUN_API_KEY"
```

[Schema definitions](https://docs.amplerun.com/reference/schemas.md) · [Download OpenAPI](/openapi.json) · [Authentication](https://docs.amplerun.com/agents/authentication.md) · [Errors and recovery](https://docs.amplerun.com/reference/errors.md)

---
Generated from the AmpleRun API contract.
Canonical: https://docs.amplerun.com/reference/api/create-job/
