# Ingest agent/resource events (idempotent per (project, dedupKey))

`POST https://api.instacloud.com/projects/{projectId}/events`

**Token scope:** `account` · `org` · `project` — read-only tokens refused (not a GET).

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `projectId` | path | `string` | yes |  |

## Request body (application/json)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `events` | `object[]` | no |  |
| `events.source` | `"agent" \| "resource"` | yes |  |
| `events.kind` | `string` | no |  |
| `events.payload` | `object` | no |  |
| `events.branchId` | `string \| null` | no |  |
| `events.dedupKey` | `string \| null` | no |  |

## Response 201

Default Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `recorded` | `integer` | no |  |
| `skipped` | `integer` | no |  |

## Response 202

Default Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `status` | `string` | yes |  |
| `approvalId` | `string` | yes |  |
| `action` | `string` | yes |  |
| `actions` | `string[]` | yes |  |
| `message` | `string` | yes |  |
| `url` | `string` | yes |  |

## Response 400

Default Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | `string` | yes |  |

## Response 403

Default Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `error` | `string` | yes |  |
