# Artifacts

Source: https://docs.havilo.ai/reference/ai-engine/artifacts

Run envelopes include artifact metadata. Fetch each artifact body with `GET /artifacts/{id}`.

## GET /artifacts/{id}

```bash
curl https://havilo.ai/api/v1/artifacts/550e8400-e29b-41d4-a716-446655440001 \
  -H "Authorization: Bearer $HAVILO_API_KEY"
```

## Table Artifact

Table artifacts include `columns` and `rows`. Rows are objects keyed by column name whenever possible.

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "object": "artifact",
  "kind": "table",
  "title": "climate-tech Startups",
  "run_id": "550e8400-e29b-41d4-a716-446655440000",
  "created_at": 1714500018000,
  "row_count": 3,
  "columns": ["Name", "Description", "Website", "Location"],
  "rows": [
    {
      "Name": "Example Startup",
      "Description": "A short company description.",
      "Website": "https://example.com",
      "Location": "San Francisco, CA"
    }
  ]
}
```

## Text Artifact

Text artifacts contain long-form generated output.

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440003",
  "object": "artifact",
  "kind": "text",
  "title": "Company Dossier",
  "run_id": "550e8400-e29b-41d4-a716-446655440000",
  "created_at": 1714500018000,
  "content": "## Company Dossier\n\n### Background\n\n..."
}
```

## Entity-Card Artifact

Entity-card artifacts contain structured entity summary content.

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440004",
  "object": "artifact",
  "kind": "entity_card",
  "title": "Entity Card",
  "run_id": "550e8400-e29b-41d4-a716-446655440000",
  "created_at": 1714500018000,
  "content": {
    "entity": {
      "id": "550e8400-e29b-41d4-a716-446655440002"
    }
  }
}
```

## Linked Entities

Use `include=links` to return normalized artifact-to-entity links:

```bash
curl "https://havilo.ai/api/v1/artifacts/550e8400-e29b-41d4-a716-446655440003?include=links" \
  -H "Authorization: Bearer $HAVILO_API_KEY"
```

The default response is unchanged when `include=links` is omitted.

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440003",
  "object": "artifact",
  "kind": "text",
  "title": "Company Dossier",
  "created_at": 1714500018000,
  "entity_refs": [
    {
      "entity_id": "550e8400-e29b-41d4-a716-446655440002",
      "role": "subject",
      "is_primary": true,
      "source": "EXTRACTOR",
      "source_detail": "text_editor",
      "content_path": "metadata.subject_entity_id"
    }
  ]
}
```

Links cover the artifacts whose entities are structural: email recipients, and the record a dossier and its entity card are about. **Table artifacts return an empty `entity_refs`** — a table's entity references are the linked values in `rows`, so read them there. Links are also derived only once an artifact is saved; `entity_refs` is empty for a run's transient output.

Artifact links are not entity-to-entity relationships. Multiple links can be primary at the same time, and automatic extractors do not mutate manual links.

## Record links

Table cells and a run's `message` name records as markdown links:

```text
[Acme Corp](entity=550e8400-e29b-41d4-a716-446655440002)
```

| Kind          | Points at                                          |
| ------------- | -------------------------------------------------- |
| `entity`      | A record. Look it up with `GET /entities/resolve`. |
| `note`        | A note.                                            |
| `artifact`    | An artifact. Fetch it with `GET /artifacts/{id}`.  |
| `entity_type` | A record type, such as Company.                    |
| `entity_list` | A saved list.                                      |

Show the label to people; the id is for your code. These are not web URLs, so a markdown renderer
needs them turned into your own links or into plain text.

## Artifact Metadata

Run envelopes include only artifact metadata:

```json
{
  "artifacts": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "kind": "table",
      "title": "climate-tech Startups",
      "row_count": 3
    }
  ]
}
```

Use the artifact endpoint for the full body.
