# Update an app

Update only the supplied fields. Set a nullable field to null to clear it. Changes apply to runs and previews started afterwards.

`PATCH /api/platform/v1/apps/{appId}`

Required permission: `project:update`.

## Parameters

| Name | In | Type | Required | Description |

| --- | --- | --- | --- | --- |

| `appId` | path | `string` | Yes | — |

| `Idempotency-Key` | header | `string` | No | Required for service credentials. Retry the same request with the same key. |

## Request body

| Field | Type | Required | Constraints | Description |
| --- | --- | --- | --- | --- |
| `name` | `string` | No | min length 1, max length 200 | — |
| `externalId` | `string` | No | min length 1, max length 256 | — |
| `metadata` | `object` | No | — | — |
| `metadata.[key]` | `__schema0` | No | — | — |
| `runScript` | `string` | No | max length 10000 | — |
| `setupScript` | `string` | No | max length 10000 | — |
| `previewPort` | `integer` | No | min 3000, max 9999 | — |
| `defaultModel` | `string` | No | min length 1, max length 1024 | — |
| `instructions` | `string` | No | max length 100000 | — |
| `idleTimeoutMinutes` | `integer` | No | min 1, max 60 | — |

```json
{
  "runScript": "npm run dev",
  "idleTimeoutMinutes": 30
}
```

## Example request

```bash
curl --request PATCH \
  --url https://api.hoplite.sh/api/platform/v1/apps/appId \
  --header "X-Api-Key: $HOPLITE_API_KEY" \
  --header "Idempotency-Key: $HOPLITE_OPERATION_ID" \
  --header 'Content-Type: application/json' \
  --data '{
  "runScript": "npm run dev",
  "idleTimeoutMinutes": 30
}'
```

## 200 response

Success

Content type: `application/json`. Response type: `object`.

| Field | Type | Required | Constraints | Description |
| --- | --- | --- | --- | --- |
| `ok` | `boolean` | Yes | true | — |
| `app` | `object` | Yes | — | — |
| `app.id` | `string` | Yes | — | — |
| `app.name` | `string` | Yes | — | — |
| `app.externalId` | `string` | Yes | — | — |
| `app.metadata` | `object` | Yes | — | — |
| `app.metadata.[key]` | `__schema0` | No | — | — |
| `app.runScript` | `string` | Yes | — | — |
| `app.setupScript` | `string` | Yes | — | — |
| `app.previewPort` | `integer` | Yes | min -9007199254740991, max 9007199254740991 | — |
| `app.defaultModel` | `string` | Yes | — | — |
| `app.instructions` | `string` | Yes | — | — |
| `app.idleTimeoutMinutes` | `integer` | Yes | min -9007199254740991, max 9007199254740991 | — |
| `app.createdAt` | `string<date-time>` | Yes | — | — |
| `app.updatedAt` | `string<date-time>` | Yes | — | — |

```json

```

## Status codes

- `200` — Success

- `400` — Invalid request

- `401` — Authentication required

- `403` — Permission, app scope or entitlement denied

- `404` — App, source or thread not found

- `409` — Idempotency conflict or request in progress

- `413` — Request too large

- `503` — Source storage or execution unavailable