# Create a Vision Event

Create a single vision event to record an observation from your computer vision deployment.

**Required scope:** `vision-events:write` or `device:update`

{% openapi src="<https://1284666567-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fe5GEiPeDoFksvZv1vH3A%2Fuploads%2Fgit-blob-0e98238ab4157276fe00dee89f522ee5a021e711%2Fopenapi.yaml?alt=media>" path="/vision-events" method="post" %}
[openapi.yaml](https://1284666567-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fe5GEiPeDoFksvZv1vH3A%2Fuploads%2Fgit-blob-0e98238ab4157276fe00dee89f522ee5a021e711%2Fopenapi.yaml?alt=media)
{% endopenapi %}

### Example Request

```bash
curl -X POST "https://api.roboflow.com/vision-events" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "eventId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "eventType": "quality_check",
    "useCaseId": "a1b3c8e1",
    "timestamp": "2024-01-15T10:30:00Z",
    "eventData": {
      "result": "fail",
      "externalId": "batch-001"
    },
    "customMetadata": {
      "line": "A1",
      "operator": "John Doe",
      "temperature": 72.5
    }
  }'
```

### Request Body Parameters

{% hint style="info" %}
Each event must have a globally unique `eventId`. We recommend using a UUID (v4) to avoid collisions. Duplicate event IDs will overwrite previously ingested events.
{% endhint %}

**Required fields:**

* **`eventId`** (string): Globally unique identifier for the event. Use a UUID (v4).
* **`eventType`** (string): One of `quality_check`, `inventory_count`, `safety_alert`, `custom`, or `operator_feedback`.
* **`useCaseId`** (string, max 256 characters): The use case this event belongs to. See [Use Cases](https://docs.roboflow.com/deploy/vision-events/use-cases) for how to create and manage use cases.
* **`timestamp`** (string, ISO 8601): When the event occurred. Must be between one year ago and tomorrow.
* **`eventData`** (object): Type-specific event data. See [Event Data Schemas](#event-data-schemas) below for the required structure per event type.

**Optional fields:**

* **`deviceId`** (string, max 256): Identifier for the device that generated the event.
* **`streamId`** (string, max 256): Identifier for the video stream.
* **`workflowId`** (string, max 256): Identifier for the workflow that generated the event.
* **`workflowVersion`** (string, max 64): Version of the workflow.
* **`images`** (array, max 1000): Array of image objects with annotations. See [Image Objects](#image-objects) below.
* **`displayImagePosition`** (number, 0-999): The index position of the image in the `images` array to use as the primary display image. For example, `0` for the first image, `1` for the second, and so on.
* **`customMetadata`** (object, max 100 keys): Key-value pairs for custom metadata. See [Custom Metadata](#custom-metadata) below.

### Event Data Schemas

The structure of `eventData` depends on the `eventType`:

{% tabs %}
{% tab title="quality\_check" %}

```json
{
  "result": "pass",
  "externalId": "batch-001"
}
```

* **`result`** (string, optional): `"pass"` or `"fail"`.
* **`externalId`** (string, max 1000, optional): External reference ID.
  {% endtab %}

{% tab title="inventory\_count" %}

```json
{
  "location": "warehouse-a",
  "itemCount": 42,
  "itemType": "pallets",
  "externalId": "inv-2024-001"
}
```

* **`location`** (string, max 1000, optional): Where the count was taken.
* **`itemCount`** (integer, >= 0, optional): Number of items counted.
* **`itemType`** (string, max 1000, optional): Type of item counted.
* **`externalId`** (string, max 1000, optional): External reference ID.
  {% endtab %}

{% tab title="safety\_alert" %}

```json
{
  "alertType": "no_hardhat",
  "severity": "high",
  "description": "Worker detected without required PPE in zone B3.",
  "externalId": "alert-2024-001"
}
```

* **`alertType`** (string, max 256, optional): Type of alert (alphanumeric, underscores, and dashes).
* **`severity`** (string, optional): `"low"`, `"medium"`, or `"high"`.
* **`description`** (string, max 10000, optional): Description of the alert.
* **`externalId`** (string, max 1000, optional): External reference ID.
  {% endtab %}

{% tab title="custom" %}

```json
{
  "value": "Custom event data as a string",
  "externalId": "custom-2024-001"
}
```

* **`value`** (string, max 10000, optional): Freeform event data.
* **`externalId`** (string, max 1000, optional): External reference ID.
  {% endtab %}

{% tab title="operator\_feedback" %}

```json
{
  "relatedEventId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "feedback": "incorrect"
}
```

* **`relatedEventId`** (string, required): The event ID (UUID) of the event this feedback is about.
* **`feedback`** (string, required): `"correct"`, `"incorrect"`, or `"inconclusive"`.
  {% endtab %}
  {% endtabs %}

### Image Objects

To attach images to an event, you must first upload each image using the [Upload a Vision Event Image](https://docs.roboflow.com/developer/rest-api/vision-events/upload-a-vision-event-image) endpoint to get a `sourceId`. Each image object in the `images` array represents an annotated (output) image. If you also want to associate the original unannotated (input) image, upload it separately and pass its `sourceId` as the `inputSourceId`.

```json
{
  "label": "inspection-photo",
  "sourceId": "img-source-123",
  "inputSourceId": "camera-1",
  "objectDetections": [
    {
      "class": "defect",
      "x": 100,
      "y": 200,
      "width": 50,
      "height": 30,
      "confidence": 0.95
    }
  ],
  "classifications": [
    {
      "class": "damaged",
      "confidence": 0.87
    }
  ],
  "instanceSegmentations": [
    {
      "class": "crack",
      "x": 100,
      "y": 200,
      "width": 50,
      "height": 30,
      "confidence": 0.92,
      "points": [[100, 200], [120, 210], [110, 230]]
    }
  ],
  "keypoints": [
    {
      "class": "joint",
      "x": 100,
      "y": 200,
      "width": 50,
      "height": 30,
      "confidence": 0.88,
      "keypoints": [
        { "id": 0, "x": 105, "y": 205, "occluded": false },
        { "id": 1, "x": 115, "y": 215 }
      ]
    }
  ]
}
```

**Image fields:**

* **`label`** (string, optional): A label for the image.
* **`sourceId`** (string, optional): The `sourceId` returned from [uploading the annotated image](https://docs.roboflow.com/developer/rest-api/vision-events/upload-a-vision-event-image).
* **`inputSourceId`** (string, optional): The `sourceId` returned from uploading the original unannotated (input) image.
* **`objectDetections`** (array, max 1000, optional): Bounding box detections with `class`, `x`, `y`, `width`, `height`, and `confidence` (0-1).
* **`classifications`** (array, max 1000, optional): Classification results with `class` and `confidence` (0-1).
* **`instanceSegmentations`** (array, max 1000, optional): Segmentation results with bounding box fields plus `points` (array of `[x, y]` pairs, minimum 3).
* **`keypoints`** (array, max 1000, optional): Keypoint detections with bounding box fields plus `keypoints` (array of objects with `id`, `x`, `y`, and optional `occluded`, minimum 1 keypoint per detection).

### Custom Metadata

You can attach up to 100 key-value pairs of custom metadata to each event. Custom metadata is queryable through the [Query Vision Events](https://docs.roboflow.com/developer/rest-api/vision-events/query-vision-events) endpoint.

**Constraints:**

* Keys must match the pattern `[a-zA-Z0-9_ -]+` (letters, digits, underscores, hyphens, and spaces), max 100 characters.
* String values are limited to 1000 characters.
* Number values support up to 6 decimal places.
* Boolean values are supported.

```json
{
  "customMetadata": {
    "production_line": "A1",
    "shift": "morning",
    "temperature": 72.5,
    "is_overtime": false
  }
}
```

### Example Response

{% tabs %}
{% tab title="201" %}

```json
{
  "eventId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "created": true
}
```

{% endtab %}

{% tab title="400" %}

```json
{
  "error": "eventType is required"
}
```

{% endtab %}

{% tab title="403" %}

```json
{
  "error": "Insufficient permissions for this resource."
}
```

{% endtab %}
{% endtabs %}

### Validation and Warnings

The Vision Events API uses eager ingestion. Only the four required fields (`eventId`, `eventType`, `useCaseId`, `timestamp`) are strictly validated. If these pass, the event is always accepted and stored, even if other fields contain errors.

Any issues with non-required fields are returned as a `warnings` array in the response rather than causing a rejection. This includes:

* Missing required fields within `eventData` (e.g., `relatedEventId` for `operator_feedback`)
* Invalid values for `eventData` fields (e.g., wrong enum value for `severity`)
* Unrecognized fields that are not part of the schema

When warnings are present, the invalid `eventData` is stored as an empty object `{}`, but the event itself is still created.

```json
{
  "eventId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "created": true,
  "warnings": [
    {
      "type": "any.required",
      "path": "eventData.relatedEventId",
      "value": null,
      "valueType": "object"
    }
  ]
}
```

The response may also include a `deprecations` array if deprecated field names were used.
