> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zylon.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Artifacts

> Workspace artifacts for documents, AI Documents, and connectors.

<Warning>
  **Upcoming release — Zylon 1.58**

  These docs are published ahead of release so you can prepare your API integrations. The release image is not yet available. For installations running 1.57, use the [1.57 documentation](/en/v1.57/overview).
</Warning>

<Warning>
  Artifact URLs, content encodings, and response fields change in 1.58. See [API migration 1.57 → 1.58](/en/v1.58/developer-manual/build-with-zylon/workspace-api/api-migration-1-57-to-1-58#artifact-routes) before upgrading your integration.
</Warning>

An artifact is a piece of information **or tool** you provide to Zylon so it can be used as context for queries and operations. The Workspace API groups artifacts into **document artifacts**, **AI Documents**, and **other artifacts**.

## Prerequisites

* An API token. See [Workspace Token Management](/en/v1.58/developer-manual/get-started/token-management).
* Your Zylon hostname (replace `{BASE_URL}` in the examples).

## Artifacts

| Category | Includes | When to use |
| - | - | - |
| **Document artifacts** | Documents, folders, links | Store or organize content inside an organization or project. |
| **AI Documents** | Summary, composition, extraction flows | Run workflows across artifacts to produce outputs. |
| **Other artifacts** | MCP servers, SQL databases, integrations, skills | Provide external tools, data sources, or reusable instructions. |

### Artifact request fields

Use `POST /api/v1/app/artifact` to create any artifact type. Ownership is supplied in the request body rather than the path. When you send `x-org`, omit `organization_id` and optionally set `project_id`; without `x-org`, Operator and SuperAdmin callers may set `organization_id`. A `project_id` always belongs to the selected organization. Set `project_id` to `null` (or omit it) to create an organization artifact; this requires an AppAdmin or higher role, and `Link` artifacts always require a project.

<Accordion title="Artifact request fields">
  | Field | Type | Required | Description |
  | - | - | - | - |
  | `organization_id` | string | Conditional | Organization identifier. Omit it when using `x-org`; otherwise it is available only to Operator and SuperAdmin callers. |
  | `project_id` | string \| null | No | Project identifier. Omit it or set it to `null` for an organization artifact. Required for `Link`. |
  | `type` | string | Yes | Artifact type: `Document`, `Folder`, `Summary`, `Composition`, `SmartDoc`, `Link`, `BulkQA`, `ReadAndExtract`, `SqlDatabase`, `McpServer`, `Integration`, `Analysis`, or `Skill`. |
  | `name` | string | Yes | Artifact display name. |
  | `props` | object | Yes | Type-specific configuration. The legacy alias `config` is also accepted. |
  | `source` | string | No | Artifact source. Production values are `User`, `SharePoint`, `GoogleDrive`, `Confluence`, `ConfluenceLocalLegacy`, `Claromentis`, `FileSystem`, `Assistant`, and `System`. Defaults to `User`. |
  | `description` | string | No | Human-readable description. |
  | `parent_id` | string | No | Parent artifact ID for tree artifacts such as documents, folders, and links. Do not use it for MCP or database artifacts. |
  | `integration_id` | string | No | Integration ID for integration-backed artifacts. The legacy alias `integration_artifact_id` is also accepted. |
  | `external_url` | string | No | External URL for link-like or connector-backed artifacts. |
  | `content` | string | Conditional | Base64-encoded content in JSON create requests. A successful `Document` or `Skill` create requires either this field or multipart `file_data`. |
  | `keep_file_after_ingestion` | boolean | No | Whether uploaded file data should be retained after ingestion. Defaults to `true`. |
  | `interaction_id` | string | No | Interaction that produced this artifact, when applicable. |
  | `private_props` | object | No | Private configuration for provider-backed `Integration`, MCP, and SQL database artifacts. The legacy alias `private_config` is also accepted on create. |
  | `scopes` | object\[] | No | Artifact visibility rules. Each item has `scope_type` (`organization` or `project`), `scope_id`, optional `enabled`, optional `ws_auto_select`, and optional `delete` (defaults to `false`). |
  | `scopes[].scope_type` | string | Yes | `organization` or `project`. |
  | `scopes[].scope_id` | string | Yes | Organization or project identifier matching `scope_type`. |
  | `scopes[].enabled` | boolean | No | Whether the artifact is visible in this scope. Defaults to `true` for a new scope. |
  | `scopes[].ws_auto_select` | boolean | No | Whether Workspace automatically selects it in this scope. Defaults to `false` for a new scope. |
  | `scopes[].delete` | boolean | No | Remove the matching scope. Defaults to `false`; normally used by update and scope operations. |
  | `file_data` | file | Conditional | Multipart-only file binary. A successful `Document` or `Skill` create requires either this field or JSON `content`. |
</Accordion>

When `scopes` is omitted, a project artifact receives its project scope and an organization artifact receives its organization scope. An organization artifact cannot be created with project scopes; add those later with the scope operation.

### Document artifacts

Document artifacts hold content, links reference existing artifacts, and folders organize artifacts inside an organization or project.

<Tabs>
  <Tab title="Document">
    <Accordion title="props body">
      | Field | Type | Required | Description |
      | - | - | - | - |
      | `file_name` | string | Yes | Original file name. |
      | `content_type` | string | Yes | MIME type of `file_data`. |
      | `content_length` | integer \| null | No | File size in bytes. It must be present and match the uploaded bytes for successful document processing; if omitted, the artifact is created in `Error` state with `ingest_status: NotApplicable`. |
      | `metadata` | object | No | Provider-specific metadata for integration-backed documents. |
      | `original_path` | string \| null | No | Original mounted path when the artifact was promoted from a thread. |
    </Accordion>

    ```bash theme={null}
    printf 'Q1 support summary.\n' > q1-support-summary.txt

    curl -X POST "https://{BASE_URL}/api/v1/app/artifact" \
      -H "Authorization: Bearer {API_TOKEN}" \
      -H "x-org: {org_slug}" \
      -F 'project_id={projectID}' \
      -F 'type=Document' \
      -F 'name=Q1 Support Summary' \
      -F 'props={
        "content_type":"text/plain",
        "file_name":"q1-support-summary.txt",
        "content_length":20
      };type=application/json' \
      -F 'file_data=@./q1-support-summary.txt;type=text/plain'
    ```

    <Accordion title="Example response">
      ```json theme={null}
      {
        "id": "artifact_doc_q1",
        "project_id": "proj_7a5c3e1b9d2f4a6c",
        "name": "Q1 Support Summary",
        "type": "Document",
        "source": "User",
        "state": "Published",
        "ingest_status": "NotStarted",
        "keep_file_after_ingestion": true,
        "props": {
          "file_name": "q1-support-summary.txt",
          "content_type": "text/plain",
          "content_length": 20
        },
        "created_at": "2026-02-08T14:30:12Z",
        "updated_at": "2026-02-08T14:31:02Z"
      }
      ```
    </Accordion>
  </Tab>

  <Tab title="Folder">
    <Accordion title="props body">
      | Field | Type | Required | Description |
      | - | - | - | - |
      | `metadata` | object | No | Provider-specific metadata for integration-backed folders. Use `{}` for user-created folders without metadata. |
    </Accordion>

    ```bash theme={null}
    curl -X POST "https://{BASE_URL}/api/v1/app/artifact" \
      -H "Authorization: Bearer {API_TOKEN}" \
      -H "x-org: {org_slug}" \
      -H "Content-Type: application/json" \
      -d '{
        "project_id": "{projectID}",
        "type": "Folder",
        "source": "User",
        "name": "Q1 Support",
        "description": "Artifacts for Q1 support work.",
        "parent_id": null,
        "props": {}
      }'
    ```

    <Accordion title="Example response">
      ```json theme={null}
      {
        "id": "artifact_folder_q1",
        "project_id": "proj_7a5c3e1b9d2f4a6c",
        "name": "Q1 Support",
        "type": "Folder",
        "source": "User",
        "state": "Published",
        "child_count": 0,
        "ingest_status": "NotApplicable",
        "props": {},
        "created_at": "2026-02-08T14:32:10Z",
        "updated_at": "2026-02-08T14:32:10Z"
      }
      ```
    </Accordion>
  </Tab>

  <Tab title="Link">
    <Accordion title="props body">
      | Field | Type | Required | Description |
      | - | - | - | - |
      | `original_artifact_id` | string | Yes | Artifact to link into this project or folder. |
      | `source_artifact_id` | string | Response only | Canonical source artifact ID. The server sets this value. |
      | `original_artifact_type` | string | Response only | Type of the original artifact. The server sets this value. |
      | `original_project_id` | string \| null | Response only | Project that owns the original artifact, when available. |
    </Accordion>

    ```bash theme={null}
    curl -X POST "https://{BASE_URL}/api/v1/app/artifact" \
      -H "Authorization: Bearer {API_TOKEN}" \
      -H "x-org: {org_slug}" \
      -H "Content-Type: application/json" \
      -d '{
        "project_id": "{projectID}",
        "type": "Link",
        "source": "User",
        "name": "Q1 Support Summary (link)",
        "description": "Reference to the canonical document.",
        "parent_id": "artifact_folder_q1",
        "props": {
          "original_artifact_id": "{artifactID}"
        }
      }'
    ```

    <Accordion title="Example response">
      ```json theme={null}
      {
        "id": "artifact_link_q1",
        "project_id": "proj_7a5c3e1b9d2f4a6c",
        "name": "Q1 Support Summary",
        "parent_id": "artifact_folder_q1",
        "type": "Link",
        "source": "User",
        "state": "Published",
        "ingest_status": "NotApplicable",
        "props": {
          "source_artifact_id": "artifact_doc_q1",
          "original_artifact_id": "artifact_doc_q1",
          "original_artifact_type": "Document",
          "original_project_id": "proj_7a5c3e1b9d2f4a6c"
        },
        "created_at": "2026-02-08T14:33:22Z",
        "updated_at": "2026-02-08T14:33:22Z"
      }
      ```
    </Accordion>

    The server copies the original artifact's name and source onto the link response.
  </Tab>
</Tabs>

### AI Documents

AI Documents run a Zylon workflow across one or more artifacts to produce a structured output.

<Tabs>
  <Tab title="Summary">
    <Accordion title="props body">
      | Field | Type | Required | Description |
      | - | - | - | - |
      | `artifact_ids` | string\[] | Yes | Input artifacts to summarize. |
      | `style` | string | Yes | `Expert`, `Neutral`, or `Simple`. Deprecated values may still decode but should not be used. |
      | `detail` | string | Yes | `KeyPoints`, `ShortPieces`, or `LongPieces`. Deprecated values may still decode but should not be used. |
      | `instructions` | string\[] \| null | No | Extra instructions for the summary generation. Omitted and `null` are equivalent. |
    </Accordion>

    ```bash theme={null}
    curl -X POST "https://{BASE_URL}/api/v1/app/artifact" \
      -H "Authorization: Bearer {API_TOKEN}" \
      -H "x-org: {org_slug}" \
      -H "Content-Type: application/json" \
      -d '{
        "project_id": "{projectID}",
        "type": "Summary",
        "source": "User",
        "name": "Q1 Support Summary (auto)",
        "props": {
          "artifact_ids": ["{artifactID}"],
          "style": "Neutral",
          "detail": "KeyPoints",
          "instructions": ["Focus on billing and onboarding trends."]
        }
      }'
    ```

    <Accordion title="Example response">
      ```json theme={null}
      {
        "id": "artifact_summary_q1",
        "project_id": "proj_7a5c3e1b9d2f4a6c",
        "type": "Summary",
        "state": "Processing",
        "ingest_status": "NotApplicable",
        "props": {
          "artifact_ids": ["artifact_doc_q1"],
          "style": "Neutral",
          "detail": "KeyPoints",
          "instructions": ["Focus on billing and onboarding trends."]
        },
        "created_at": "2026-02-08T15:10:00Z"
      }
      ```
    </Accordion>
  </Tab>

  <Tab title="Composition">
    <Accordion title="props body">
      | Field | Type | Required | Description |
      | - | - | - | - |
      | `artifact_ids` | string\[] | Yes | Input artifacts to use for the draft. |
      | `instructions` | string | Yes | Composition prompt or drafting instructions. |
      | `style` | string | Yes | `Expert`, `Neutral`, or `Simple`. |
      | `detail` | string | Yes | `KeyPoints`, `ShortPieces`, or `LongPieces`. |
    </Accordion>

    ```bash theme={null}
    curl -X POST "https://{BASE_URL}/api/v1/app/artifact" \
      -H "Authorization: Bearer {API_TOKEN}" \
      -H "x-org: {org_slug}" \
      -H "Content-Type: application/json" \
      -d '{
        "project_id": "{projectID}",
        "type": "Composition",
        "source": "User",
        "name": "Q1 Support Brief",
        "props": {
          "artifact_ids": ["{artifactID}"],
          "style": "Expert",
          "detail": "LongPieces",
          "instructions": "Draft a one-page summary for leadership."
        }
      }'
    ```

    <Accordion title="Example response">
      ```json theme={null}
      {
        "id": "artifact_comp_q1",
        "project_id": "proj_7a5c3e1b9d2f4a6c",
        "type": "Composition",
        "state": "Processing",
        "ingest_status": "NotApplicable",
        "props": {
          "artifact_ids": ["artifact_doc_q1"],
          "style": "Expert",
          "detail": "LongPieces",
          "instructions": "Draft a one-page summary for leadership."
        },
        "created_at": "2026-02-08T15:12:40Z"
      }
      ```
    </Accordion>
  </Tab>

  <Tab title="BulkQA">
    <Accordion title="props body">
      | Field | Type | Required | Description |
      | - | - | - | - |
      | `questions` | string\[] | Yes | Questions to answer. |
      | `artifact_ids` | string\[] | Yes | Input artifacts to answer from. |
      | `instructions` | string\[] | Yes | Constraints or guidance for the answers. |
      | `detail` | string | Yes | `Concise`, `Moderate`, or `Comprehensive`. |
      | `style` | string | Yes | `Expert`, `Neutral`, or `Simple`. |
      | `results` | object\[] | No | Server-populated answer results. Defaults to `[]`. |
    </Accordion>

    ```bash theme={null}
    curl -X POST "https://{BASE_URL}/api/v1/app/artifact" \
      -H "Authorization: Bearer {API_TOKEN}" \
      -H "x-org: {org_slug}" \
      -H "Content-Type: application/json" \
      -d '{
        "project_id": "{projectID}",
        "type": "BulkQA",
        "source": "User",
        "name": "Billing FAQ",
        "props": {
          "artifact_ids": ["{artifactID}"],
          "style": "Simple",
          "detail": "Concise",
          "instructions": ["Answer using only the artifacts."],
          "questions": [
            "What are the top billing issues?",
            "How quickly were priority bugs resolved?"
          ]
        }
      }'
    ```

    <Accordion title="Example response">
      ```json theme={null}
      {
        "id": "artifact_bulkqa_q1",
        "project_id": "proj_7a5c3e1b9d2f4a6c",
        "type": "BulkQA",
        "state": "Processing",
        "ingest_status": "NotApplicable",
        "props": {
          "artifact_ids": ["artifact_doc_q1"],
          "style": "Simple",
          "detail": "Concise",
          "instructions": ["Answer using only the artifacts."],
          "questions": [
            "What are the top billing issues?",
            "How quickly were priority bugs resolved?"
          ],
          "results": []
        },
        "created_at": "2026-02-08T15:14:10Z"
      }
      ```
    </Accordion>
  </Tab>

  <Tab title="ReadAndExtract">
    <Accordion title="props body">
      | Field | Type | Required | Description |
      | - | - | - | - |
      | `artifact_ids` | string\[] | Yes | Input artifacts to read. |
      | `sections` | object\[] | Yes | Extraction targets. |
      | `sections[].id` | string | Yes | Stable section ID. |
      | `sections[].title` | string | Yes | Section title. |
      | `sections[].description` | string | Yes | What to extract for that section. |
      | `results` | object\[] | Response only | Extracted section results. |
      | `organization_context` | string \| null | Response only | Organization context used by the server. |
    </Accordion>

    ```bash theme={null}
    curl -X POST "https://{BASE_URL}/api/v1/app/artifact" \
      -H "Authorization: Bearer {API_TOKEN}" \
      -H "x-org: {org_slug}" \
      -H "Content-Type: application/json" \
      -d '{
        "project_id": "{projectID}",
        "type": "ReadAndExtract",
        "source": "User",
        "name": "Contract extraction",
        "props": {
          "artifact_ids": ["{artifactID}"],
          "sections": [
            { "title": "Term", "description": "Contract term in months", "id": "term" },
            { "title": "SLA", "description": "Support response time", "id": "sla" }
          ]
        }
      }'
    ```

    <Accordion title="Example response">
      ```json theme={null}
      {
        "id": "artifact_readextract_v3",
        "project_id": "proj_7a5c3e1b9d2f4a6c",
        "type": "ReadAndExtract",
        "state": "Processing",
        "ingest_status": "NotApplicable",
        "props": {
          "artifact_ids": ["artifact_doc_q1"],
          "sections": [
            { "title": "Term", "description": "Contract term in months", "id": "term" },
            { "title": "SLA", "description": "Support response time", "id": "sla" }
          ],
          "results": []
        },
        "created_at": "2026-02-08T15:15:55Z"
      }
      ```
    </Accordion>
  </Tab>

  <Tab title="Analysis">
    <Accordion title="props body">
      | Field | Type | Required | Description |
      | - | - | - | - |
      | `artifact_ids` | string\[] | Yes | Input artifacts to analyze. |
      | `instruction` | object \| null | No | Custom analysis instruction. If omitted, the server uses its default analysis prompt. |
      | `instruction.id` | string | Yes when `instruction` is set | Stable instruction ID. |
      | `instruction.prompt` | string | Yes when `instruction` is set | Prompt used for analysis. |
      | `instruction.metadata` | object | No | String keys and string values. Defaults to `{}`. |
      | `result` | object \| null | Response only | Combined analysis output. |
      | `organization_context` | string \| null | Response only | Organization context used by the server. |
    </Accordion>

    ```bash theme={null}
    curl -X POST "https://{BASE_URL}/api/v1/app/artifact" \
      -H "Authorization: Bearer {API_TOKEN}" \
      -H "x-org: {org_slug}" \
      -H "Content-Type: application/json" \
      -d '{
        "project_id": "{projectID}",
        "type": "Analysis",
        "source": "User",
        "name": "Support trend analysis",
        "props": {
          "artifact_ids": ["{artifactID}"],
          "instruction": {
            "id": "support_trends",
            "prompt": "Find the top support trends and risks.",
            "metadata": { "audience": "leadership" }
          }
        }
      }'
    ```

    <Accordion title="Example response">
      ```json theme={null}
      {
        "id": "artifact_analysis_q1",
        "project_id": "proj_7a5c3e1b9d2f4a6c",
        "type": "Analysis",
        "state": "Processing",
        "ingest_status": "NotApplicable",
        "props": {
          "artifact_ids": ["artifact_doc_q1"],
          "instruction": {
            "id": "support_trends",
            "prompt": "Find the top support trends and risks.",
            "metadata": { "audience": "leadership" }
          }
        },
        "created_at": "2026-02-08T15:16:30Z"
      }
      ```
    </Accordion>
  </Tab>

  <Tab title="SmartDoc">
    <Accordion title="props body">
      SmartDoc creation accepts `props`, but the server initializes SmartDoc artifacts with an empty object. Send `{}`.
    </Accordion>

    ```bash theme={null}
    curl -X POST "https://{BASE_URL}/api/v1/app/artifact" \
      -H "Authorization: Bearer {API_TOKEN}" \
      -H "x-org: {org_slug}" \
      -H "Content-Type: application/json" \
      -d '{
        "project_id": "{projectID}",
        "type": "SmartDoc",
        "source": "User",
        "name": "Onboarding SmartDoc",
        "props": {}
      }'
    ```

    <Accordion title="Example response">
      ```json theme={null}
      {
        "id": "artifact_smartdoc_q1",
        "project_id": "proj_7a5c3e1b9d2f4a6c",
        "type": "SmartDoc",
        "state": "Draft",
        "ingest_status": "NotApplicable",
        "props": {},
        "created_at": "2026-02-08T15:17:20Z"
      }
      ```
    </Accordion>
  </Tab>
</Tabs>

### Other artifacts

Other artifacts provide tools, provider connections, and reusable skills. `private_props` is used by **MCP**, **SQL database**, and provider-backed `Integration` artifacts. For `Integration` request shapes, see the [Confluence](/en/v1.58/developer-manual/build-with-zylon/workspace-api/integrations/confluence), [SharePoint](/en/v1.58/developer-manual/build-with-zylon/workspace-api/integrations/sharepoint), [Filesystem](/en/v1.58/developer-manual/build-with-zylon/workspace-api/integrations/filesystem), and [Claromentis](/en/v1.58/developer-manual/build-with-zylon/workspace-api/integrations/claromentis) guides.

<Tabs>
  <Tab title="SqlDatabase">
    <Accordion title="props body">
      | Field | Type | Required | Description |
      | - | - | - | - |
      | `schemas` | string\[] \| null | No | Database schemas to expose. |
      | `tables` | string\[] \| null | No | Database tables to expose. |
      | `ssl` | boolean \| null | No | Whether the database connection uses SSL. Runtime default: `true`. |
      | `enable_tables` | boolean \| null | No | Enable table discovery/use. Runtime default: `true`. |
      | `enable_views` | boolean \| null | No | Enable view discovery/use. Runtime default: `true`. |
      | `enable_procedures` | boolean \| null | No | Enable stored procedure discovery/use. Runtime default: `false`. |
      | `enable_functions` | boolean \| null | No | Enable function discovery/use. Runtime default: `false`. |
      | `private_props.connection_string` | string | Yes | Database connection string. Mask secrets in examples and logs. |
    </Accordion>

    ```bash theme={null}
    curl -X POST "https://{BASE_URL}/api/v1/app/artifact" \
      -H "Authorization: Bearer {API_TOKEN}" \
      -H "x-org: {org_slug}" \
      -H "Content-Type: application/json" \
      -d '{
        "project_id": "{projectID}",
        "type": "SqlDatabase",
        "source": "User",
        "name": "Sales database",
        "description": "Read-only reporting database.",
        "props": {
          "schemas": ["public", "analytics"],
          "tables": ["orders", "customers"],
          "ssl": true,
          "enable_tables": true,
          "enable_views": true,
          "enable_procedures": false,
          "enable_functions": false
        },
        "private_props": {
          "connection_string": "postgresql://readonly:***@db.example.com:5432/sales"
        }
      }'
    ```

    <Accordion title="Example response">
      ```json theme={null}
      {
        "id": "artifact_db_sales",
        "project_id": "proj_7a5c3e1b9d2f4a6c",
        "type": "SqlDatabase",
        "state": "Published",
        "ingest_status": "NotApplicable",
        "props": {
          "schemas": ["public", "analytics"],
          "tables": ["orders", "customers"],
          "ssl": true,
          "enable_tables": true,
          "enable_views": true,
          "enable_procedures": false,
          "enable_functions": false
        },
        "created_at": "2026-02-08T15:20:05Z"
      }
      ```
    </Accordion>
  </Tab>

  <Tab title="McpServer">
    <Accordion title="props body">
      | Field | Type | Required | Description |
      | - | - | - | - |
      | `name` | string | Yes | MCP server name visible to tools. |
      | `tool_configuration` | object \| null | No | Tool allowlist configuration. |
      | `tool_configuration.enabled` | boolean | No | Whether tools are enabled. Defaults to `true`. |
      | `tool_configuration.allowed_tools` | string\[] \| null | No | Tool names clients may call through this MCP server. |
      | `private_props.url` | string | Yes | MCP server URL. |
      | `private_props.use_bearer_auth` | boolean | No | Whether to authenticate with bearer auth. Defaults to `false`. |
      | `private_props.authorization_token` | string \| null | No | Authorization token when the server expects a custom authorization token. Mask the value. |
      | `private_props.refresh_token` | string \| null | No | OAuth refresh token. Mask the value. |
      | `private_props.client_id` | string \| null | No | OAuth client identifier. |
      | `private_props.client_secret` | string \| null | No | OAuth client secret. Mask the value. |
      | `private_props.bearer_token` | string \| null | No | Bearer token when bearer auth is enabled. Mask the value. |
    </Accordion>

    ```bash theme={null}
    curl -X POST "https://{BASE_URL}/api/v1/app/artifact" \
      -H "Authorization: Bearer {API_TOKEN}" \
      -H "x-org: {org_slug}" \
      -H "Content-Type: application/json" \
      -d '{
        "project_id": "{projectID}",
        "type": "McpServer",
        "source": "User",
        "name": "Internal tools",
        "props": {
          "name": "internal_mcp",
          "tool_configuration": {
            "enabled": true,
            "allowed_tools": ["crm_lookup", "ticket_search"]
          }
        },
        "private_props": {
          "url": "https://mcp.example.com",
          "authorization_token": "***"
        }
      }'
    ```

    <Accordion title="Example response">
      ```json theme={null}
      {
        "id": "artifact_mcp_internal",
        "project_id": "proj_7a5c3e1b9d2f4a6c",
        "type": "McpServer",
        "state": "Published",
        "ingest_status": "NotApplicable",
        "props": {
          "name": "internal_mcp",
          "tool_configuration": {
            "enabled": true,
            "allowed_tools": ["crm_lookup", "ticket_search"]
          }
        },
        "created_at": "2026-02-08T15:22:30Z"
      }
      ```
    </Accordion>
  </Tab>

  <Tab title="Skill">
    <Accordion title="props body">
      | Field | Type | Required | Description |
      | - | - | - | - |
      | `skill_id` | string \| null | No | Server-generated skill ID. Omit it when creating a skill. |
      | `versions` | string\[] | Response only | Available skill versions. |
      | `current_version` | string \| null | Response only | Active skill version. |
      | `content_md5` | string \| null | No | Server-generated content hash. Omit it when creating a skill. |
      | `name` | string | Yes | Stable skill name. |
      | `display_title` | string | Yes | Skill title shown in Workspace. |
      | `display_description` | string \| null | No | Human-readable description. |
      | `source` | string | No | `custom`, `anthropic`, or `zylon`. Defaults to `custom`. |
      | `loading` | string | No | `lazy` or `eager`. Defaults to `lazy`. |
    </Accordion>

    ```bash theme={null}
    curl -X POST "https://{BASE_URL}/api/v1/app/artifact" \
      -H "Authorization: Bearer {API_TOKEN}" \
      -H "x-org: {org_slug}" \
      -F 'project_id={projectID}' \
      -F 'type=Skill' \
      -F 'name=Ticket triage' \
      -F 'props={
        "name":"ticket-triage",
        "display_title":"Ticket triage",
        "display_description":"Classify and route support tickets.",
        "source":"custom",
        "loading":"lazy"
      };type=application/json' \
      -F 'file_data=@./skill.zip;type=application/zip'
    ```

    <Accordion title="Example response">
      ```json theme={null}
      {
        "id": "artifact_skill_triage",
        "project_id": "proj_7a5c3e1b9d2f4a6c",
        "type": "Skill",
        "source": "User",
        "state": "Published",
        "ingest_status": "NotApplicable",
        "props": {
          "skill_id": "skill_ticket_triage",
          "versions": ["1"],
          "current_version": "1",
          "content_md5": "{CONTENT_MD5}",
          "name": "ticket-triage",
          "display_title": "Ticket triage",
          "display_description": "Classify and route support tickets.",
          "source": "custom",
          "loading": "lazy"
        }
      }
      ```
    </Accordion>
  </Tab>
</Tabs>

## Working with artifacts

### List artifacts

Use `GET /api/v1/app/artifact`. With `x-org`, omit `organization_id`; use `project_id` to narrow the result to one project or omit it to list the artifacts visible across the selected organization. Without `x-org`, Operator and SuperAdmin callers can select an organization with `organization_id`, or omit both ownership parameters for a cross-organization list of accessible artifacts.

<Accordion title="Endpoint parameters">
  | Query parameter | Type | Required | Description |
  | - | - | - | - |
  | `organization_id` | string | Conditional | Organization to list when `x-org` is omitted. Cannot be combined with `x-org`. |
  | `project_id` | string | No | Project within the selected organization. Requires `organization_id` when `x-org` is omitted. |
  | `state` | string | No | Comma-separated values from `Initializing`, `Processing`, `Draft`, `Deleted`, `Published`, `Unavailable`, and `Error`. Defaults to `Published,Processing`. |
  | `source` | string | No | Comma-separated artifact sources. Defaults to all sources. |
  | `ingest_status` | string | No | Comma-separated values from `NotApplicable`, `NotStarted`, `Processing`, `Parsing`, `Storing`, `Done`, and `Error`. Defaults to all statuses. |
  | `type` | string | No | Comma-separated artifact types. |
  | `scopes` | JSON array | No | Scope filters. Each item requires `scope_type`, `scope_id`, and boolean `enabled`. `ws_auto_select` is optional and defaults to `false`, but does not affect filtering. |
  | `parent_id` | string | No | Scope results to direct children of a parent artifact. |
  | `include_descendants` | boolean | No | Include the full subtree under `parent_id`; if no parent is set, include all descendants in the selected scope. |
  | `filter_by_text` | string | No | Text search over artifact names. |
  | `keep_ancestors` | boolean | No | Include ancestors of artifacts that match the complete query. |
  | `resolve_links` | boolean | No | Resolve Link artifacts in project listings. Without `parent_id`, link descendants are added only with `include_descendants=true`; with a Link parent, returns its direct children or its full subtree according to `include_descendants`. |
  | `sub_type` | string | No | Comma-separated artifact types used to filter link targets by `props.original_artifact_type`; artifacts without that property are also retained. |
  | `include` | string | No | Comma-separated list of `Account`, `Project`, `Organization`, `Scopes`, and `Relationships`. Use `Account` to include creator details. |
  | `order_by` | string | No | `Alphabetical` or `CreatedAt`. |
  | `order` | string | No | `ASC` or `DESC`. Defaults to `ASC`. |
  | `created_by` | string | No | Account ID that created the artifacts. |
  | `created_by_state` | string | No | Creator account state: `Active` or `Inactive`. |
  | `start_date`, `end_date` | integer | No | Inclusive creation-time bounds as Unix epoch milliseconds. |
  | `page` | integer | No | Zero-based page number. Cannot be combined with cursor parameters. |
  | `page_size` | integer | No | Items per page when `page` is set. Defaults to `50`; cursor pagination uses `first` or `last` instead. |
  | `page_order` | string | No | ID ordering for absolute pagination: `ASC` or `DESC`. Defaults to `ASC`. |
  | `after`, `before` | string | No | Artifact ID cursors for forward or backward pagination. |
  | `first`, `last` | integer | No | Positive result limit after or before a cursor. |
  | `total_count` | boolean | No | Include `total_count` in the response. Defaults to `false`. |
</Accordion>

```bash theme={null}
curl "https://{BASE_URL}/api/v1/app/artifact?project_id={projectID}&page=0&page_size=20&total_count=true&parent_id={artifactID}&include_descendants=false&include=Account,Scopes" \
  -H "Authorization: Bearer {API_TOKEN}" \
  -H "x-org: {org_slug}"
```

<Accordion title="Example response">
  ```json theme={null}
  {
    "data": [
      {
        "id": "artifact_doc_q1",
        "project_id": "proj_7a5c3e1b9d2f4a6c",
        "name": "Q1 Support Summary",
        "type": "Document",
        "source": "User",
        "state": "Published",
        "ingest_status": "Done",
        "parent_id": "artifact_folder_q1",
        "child_count": 0,
        "keep_file_after_ingestion": true,
        "scopes": [
          {
            "scope_type": "project",
            "scope_id": "proj_7a5c3e1b9d2f4a6c",
            "enabled": true,
            "ws_auto_select": false
          }
        ],
        "created_by": {
          "id": "acct_6c8a1f3b2d4e5f7a",
          "state": "Active",
          "email": "sasha@example.com",
          "name": "Sasha Patel",
          "profile_picture": "https://{BASE_URL}/files/profile-picture.png",
          "provider": "Credentials",
          "roles": ["Workspace"],
          "created_at": "2026-02-08T14:12:45Z",
          "updated_at": "2026-02-08T14:12:45Z"
        },
        "created_at": "2026-02-08T14:30:12Z",
        "updated_at": "2026-02-08T14:31:02Z"
      }
    ],
    "has_next_page": false,
    "has_previous_page": false,
    "total_count": 1
  }
  ```
</Accordion>

The page response also returns `next_cursor` and `previous_cursor` when those cursors are available. `has_next_page` and `has_previous_page` are always present; `total_count` is returned only when `total_count=true`.

### Get an artifact

`GET /api/v1/app/artifact/{artifactID}` derives the organization and project from the stored artifact.

<Accordion title="Endpoint parameters">
  | Parameter | Type | Required | Description |
  | - | - | - | - |
  | `artifactID` | path | Yes | Artifact identifier. |
  | `include_references` | boolean | No | Include referenced artifacts. Defaults to `true`. |
  | `include_relationships` | boolean | No | Include artifact relationships. Defaults to the value of `include_references`. |
</Accordion>

```bash theme={null}
curl "https://{BASE_URL}/api/v1/app/artifact/{artifactID}?include_references=true&include_relationships=true" \
  -H "Authorization: Bearer {API_TOKEN}" \
  -H "x-org: {org_slug}"
```

<Accordion title="Example response">
  ```json theme={null}
  {
    "id": "artifact_doc_q1",
    "project_id": "proj_7a5c3e1b9d2f4a6c",
    "name": "Q1 Support Summary",
    "type": "Document",
    "source": "User",
    "state": "Published",
    "ingest_status": "Done",
    "parent_id": "artifact_folder_q1",
    "child_count": 0,
    "props": {
      "file_name": "q1-support-summary.txt",
      "content_type": "text/plain",
      "content_length": 20
    },
    "keep_file_after_ingestion": true,
    "scopes": [
      {
        "scope_type": "project",
        "scope_id": "proj_7a5c3e1b9d2f4a6c",
        "enabled": true,
        "ws_auto_select": false
      }
    ],
    "created_by": {
      "id": "acct_6c8a1f3b2d4e5f7a",
      "state": "Active",
      "email": "sasha@example.com",
      "name": "Sasha Patel",
      "profile_picture": "https://{BASE_URL}/files/profile-picture.png",
      "provider": "Credentials",
      "roles": ["Workspace"],
      "created_at": "2026-02-08T14:12:45Z",
      "updated_at": "2026-02-08T14:12:45Z"
    },
    "created_at": "2026-02-08T14:30:12Z",
    "updated_at": "2026-02-08T14:31:02Z"
  }
  ```
</Accordion>

| Response field | Type | Description |
| - | - | - |
| `id` | string | Artifact ID. |
| `parent_id` | string \| null | Parent artifact ID, when the artifact is nested. |
| `child_count` | integer | Number of direct children. |
| `project_id` | string \| null | Project ID, or `null` for an organization artifact. |
| `project` | object \| null | Project details when requested with `include=Project` in list responses. |
| `organization` | object \| null | Organization details when requested with `include=Organization` in list responses. |
| `name` | string | Artifact name. |
| `description` | string \| null | Artifact description. |
| `type` | string | Artifact type. |
| `source` | string | Artifact source. |
| `state` | string | `Initializing`, `Processing`, `Draft`, `Deleted`, `Published`, `Unavailable`, or `Error`. |
| `error` | string \| null | Ingest or processing error code. |
| `ingest_status` | string | `NotApplicable`, `NotStarted`, `Processing`, `Parsing`, `Storing`, `Done`, or `Error`. |
| `ingest_warnings` | string\[] \| null | Non-fatal ingest warnings. |
| `ingest_progress` | number \| null | Ingest progress when available. |
| `integration_id` | string \| null | Integration ID for integration-backed artifacts. |
| `external_url` | string \| null | External URL when present. |
| `props` | object | Type-specific public configuration. |
| `file_uri` | string \| null | Temporary public file URL when available. |
| `artifact_references` | object\[] \| null | References when `include_references=true`. |
| `artifact_relationships` | object\[] \| null | Published relationships when `include_relationships=true`. |
| `artifact_relationships[].node_id` | string | Identifier of the related artifact node. |
| `artifact_relationships[].node_type` | string | Type of the related artifact node. |
| `keep_file_after_ingestion` | boolean | Whether uploaded file data is retained. |
| `created_by` | object \| null | Creator `AccountDTO`. Returned for artifact details and in list results when `include=Account`. |
| `created_at` | timestamp | Creation timestamp. |
| `updated_at` | timestamp | Last update timestamp. |
| `etag` | string \| null | Content entity tag when available. |
| `scopes` | object\[] \| null | Visibility rules. Each response item contains `scope_type`, `scope_id`, `enabled`, and `ws_auto_select`. |

### Update an artifact

Use `PUT /api/v1/app/artifact/{artifactID}`. The server derives ownership from the existing artifact.

<Accordion title="Endpoint parameters">
  | Field | Type | Required | Description |
  | - | - | - | - |
  | `artifactID` | path | Yes | Artifact identifier. |
  | `name` | string | No | New artifact name. |
  | `parent_id` | string | No | Move a content/tree artifact under this parent artifact. Do not use it for MCP or database artifacts. |
  | `reset_parent_id` | boolean | No | Set to `true` to move a content/tree artifact to the root of its project or organization tree. Defaults to `false`. |
  | `external_url` | string | No | Replace the external URL. |
  | `props` | object | No | Replace or update type-specific public configuration. The legacy alias `config` is also accepted. |
  | `description` | string | No | Replace the description. |
  | `content` | string | No | Plain UTF-8 content in a JSON request. |
  | `private_props` | object | No | Private configuration for provider-backed `Integration`, MCP, and SQL database artifacts. |
  | `scopes` | object\[] | No | Scope changes using the same shape as create requests. Set an item's `delete` to `true` to remove that scope. |
  | `file_data` | file | No | Multipart-only replacement file. Other update fields can be submitted as multipart form fields. |
</Accordion>

```bash theme={null}
curl -X PUT "https://{BASE_URL}/api/v1/app/artifact/{artifactID}" \
  -H "Authorization: Bearer {API_TOKEN}" \
  -H "x-org: {org_slug}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Q1 Support Summary (final)",
    "description": "Finalized weekly summary notes.",
    "parent_id": "artifact_folder_q1",
    "reset_parent_id": false,
    "content": "Ticket volume rose 12% week-over-week..."
  }'
```

<Accordion title="Example response">
  ```json theme={null}
  {
    "id": "artifact_doc_q1",
    "name": "Q1 Support Summary (final)",
    "description": "Finalized weekly summary notes.",
    "parent_id": "artifact_folder_q1",
    "type": "Document",
    "source": "User",
    "ingest_status": "Done",
    "updated_at": "2026-02-08T14:45:21Z"
  }
  ```
</Accordion>

<Tip>
  Use `parent_id` to move an artifact into a folder. Use `reset_parent_id: true` to remove the current parent and move it to the root of its project or organization tree.
</Tip>

### Validate create and update requests

Validate a create payload with `POST /api/v1/app/artifact/validate`. It accepts the same JSON or multipart body as create. Validate a JSON update payload with `POST /api/v1/app/artifact/{artifactID}/validate`; file replacement multipart bodies are validated when submitted to the update operation itself. Validation does not persist the change. These validation operations currently support `Skill` and `SqlDatabase` artifacts.

```bash theme={null}
curl -X POST "https://{BASE_URL}/api/v1/app/artifact/validate" \
  -H "Authorization: Bearer {API_TOKEN}" \
  -H "x-org: {org_slug}" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "{projectID}",
    "type": "SqlDatabase",
    "name": "Sales database",
    "props": {
      "ssl": true,
      "enable_tables": true
    },
    "private_props": {
      "connection_string": "{DATABASE_CONNECTION_STRING}"
    }
  }'
```

<Accordion title="Example response">
  ```json theme={null}
  {
    "valid": true,
    "errors": [],
    "warnings": []
  }
  ```
</Accordion>

The response contains `valid`, `errors`, and `warnings`, plus optional `data`. Each error or warning contains `type`, `message`, and optional `params`. Skill validation can return parsed `name` and `description` values in `data`.

To validate an update against the artifact's stored configuration:

```bash theme={null}
curl -X POST "https://{BASE_URL}/api/v1/app/artifact/{artifactID}/validate" \
  -H "Authorization: Bearer {API_TOKEN}" \
  -H "x-org: {org_slug}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Sales database (validated)"
  }'
```

<span id="artifact-scope-changes" style={{ display: "block", scrollMarginTop: "8rem" }} />

### Add, update, or remove a scope

Use `POST /api/v1/app/artifact/{artifactID}/scope` for one scope change. The response is the updated artifact with its current `scopes`.

```bash theme={null}
curl -X POST "https://{BASE_URL}/api/v1/app/artifact/{artifactID}/scope" \
  -H "Authorization: Bearer {API_TOKEN}" \
  -H "x-org: {org_slug}" \
  -H "Content-Type: application/json" \
  -d '{
    "scope_type": "project",
    "scope_id": "{projectID}",
    "enabled": true,
    "ws_auto_select": false,
    "delete": false
  }'
```

Set `delete` to `true` to remove the matching scope.

### Retry an artifact

`POST /api/v1/app/artifact/{artifactID}/retry` deletes the existing artifact and creates a replacement from a create-artifact payload. The payload's organization and project must match the original artifact. The response is the replacement `ArtifactDTO`, which has a new artifact ID.

```bash theme={null}
curl -X POST "https://{BASE_URL}/api/v1/app/artifact/{artifactID}/retry" \
  -H "Authorization: Bearer {API_TOKEN}" \
  -H "x-org: {org_slug}" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "{projectID}",
    "type": "Document",
    "name": "Q1 Support Summary",
    "props": {
      "file_name": "q1-support-summary.txt",
      "content_type": "text/plain",
      "content_length": 38
    },
    "content": "VGlja2V0IHZvbHVtZSByb3NlIDEyJSB3ZWVrLW92ZXItd2Vlay4="
  }'
```

### Delete an artifact

Deleting a parent can delete more than one artifact. The response is therefore always an array of deleted artifact details.

```bash theme={null}
curl -X DELETE "https://{BASE_URL}/api/v1/app/artifact/{artifactID}" \
  -H "Authorization: Bearer {API_TOKEN}" \
  -H "x-org: {org_slug}"
```

<Accordion title="Example response">
  ```json theme={null}
  [
    {
      "id": "artifact_doc_q1",
      "state": "Deleted",
      "type": "Document",
      "source": "User",
      "ingest_status": "Done"
    }
  ]
  ```
</Accordion>

### Download raw artifact content

Without a `Content-Disposition` header, or with `Content-Disposition: inline`, this endpoint returns a presigned URL string. Send `Content-Disposition: attachment` to stream the file bytes directly. For an available Link artifact, both modes resolve the original artifact before returning its URL or bytes.

```bash theme={null}
curl "https://{BASE_URL}/api/v1/app/artifact/{artifactID}/download" \
  -H "Authorization: Bearer {API_TOKEN}" \
  -H "x-org: {org_slug}" \
  -H "Content-Disposition: attachment" \
  --output q1-support-summary.txt
```

### Get parsed content

This endpoint is only available when the artifact has an initialized vector index.
In practice, this usually means connector-backed documents or artifacts that have completed indexing.

```bash theme={null}
curl "https://{BASE_URL}/api/v1/app/artifact/{artifactID}/parsed-content" \
  -H "Authorization: Bearer {API_TOKEN}" \
  -H "x-org: {org_slug}"
```

<Accordion title="Example response">
  ```text theme={null}
  # Q1 Support Summary

  Billing issues drove 38% of support cases.
  ```
</Accordion>

### Sync an artifact

This endpoint is primarily used for integration artifacts (SharePoint, Confluence, Claromentis, or FileSystem).

```bash theme={null}
curl -N -X POST "https://{BASE_URL}/api/v1/app/artifact/{artifactID}/sync" \
  -H "Authorization: Bearer {API_TOKEN}" \
  -H "x-org: {org_slug}" \
  -H "Accept: text/event-stream"
```

The request body is empty. The response is an SSE stream emitted by the integration sync process.

<Accordion title="Sync event fields">
  | JSON field | Type | Present for | Description |
  | - | - | - | - |
  | `type` | string | All events | `sync_started`, `sync_progress`, `sync_completed`, or `sync_error`. |
  | `current_artifact_count` | integer | `sync_started` | Existing artifact count. Defaults to `0`. |
  | `integration_item_count` | integer \| null | `sync_started` | Total provider item count when known. |
  | `integration_item` | object \| null | `sync_progress` | Provider item currently being processed. |
  | `artifact_id` | string \| null | `sync_progress` | Affected artifact identifier. |
  | `artifact` | object \| null | `sync_progress` | Affected public artifact object when included. |
  | `op` | string | `sync_progress` | `Added`, `Removed`, `Skipped`, `Updated`, `Recreated`, or `Error`. |
  | `progress` | number | `sync_progress` | Progress value. Defaults to `0`. |
  | `message` | string | `sync_error` | Error message. |
</Accordion>

<Accordion title="Example stream">
  ```text theme={null}
  event: SyncEvent
  data: {"type":"sync_started","current_artifact_count":12,"integration_item_count":40}

  event: SyncEvent
  data: {"type":"sync_progress","artifact_id":"artifact_doc_q1","op":"Updated","progress":0.42}

  event: SyncEvent
  data: {"type":"sync_completed"}
  ```
</Accordion>

### Ingest from an integration artifact

Use `POST /api/v1/app/artifact/{artifactID}/ingest` to start an initial ingestion from an `Integration` artifact. The JSON body is provider-specific and must include the target `project_id`. The example below selects a Confluence space; see each integration guide for its complete selection fields. The response is an SSE stream using the same sync event family shown above.

```bash theme={null}
curl -N -X POST "https://{BASE_URL}/api/v1/app/artifact/{artifactID}/ingest" \
  -H "Authorization: Bearer {API_TOKEN}" \
  -H "x-org: {org_slug}" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "project_id": "{projectID}",
    "space_ids": ["ENG"]
  }'
```

### Bulk update artifacts

Use the bulk update endpoint to apply the same update body shape used by `PUT /api/v1/app/artifact/{artifactID}` to multiple artifacts.

<Accordion title="Endpoint parameters">
  | Type | Name | Required | Notes |
  | - | - | - | - |
  | Body | `artifacts` | Yes | Array of artifact updates. |
  | Body | `artifacts[].artifactId` | Yes | Artifact identifier to update. |
  | Body | `artifacts[].update` | Yes | Update body using the same fields as `PUT /api/v1/app/artifact/{artifactID}`. |
</Accordion>

```bash theme={null}
curl -X PUT "https://{BASE_URL}/api/v1/app/artifact/bulk" \
  -H "Authorization: Bearer {API_TOKEN}" \
  -H "x-org: {org_slug}" \
  -H "Content-Type: application/json" \
  -d '{
    "artifacts": [
      {
        "artifactId": "artifact_doc_q1",
        "update": {
          "parent_id": "artifact_folder_q1",
          "reset_parent_id": false,
          "description": "Moved into Q1 folder."
        }
      }
    ]
  }'
```

<Accordion title="Example response">
  ```json theme={null}
  [
    {
      "id": "artifact_doc_q1",
      "parent_id": "artifact_folder_q1",
      "description": "Moved into Q1 folder.",
      "type": "Document",
      "state": "Published",
      "ingest_status": "Done",
      "updated_at": "2026-02-08T15:20:00Z"
    }
  ]
  ```
</Accordion>

### Bulk delete artifacts

<Accordion title="Endpoint parameters">
  | Type | Name | Required | Notes |
  | - | - | - | - |
  | Body | `artifact_ids` | Yes | Artifact identifiers to delete. |
</Accordion>

```bash theme={null}
curl -X DELETE "https://{BASE_URL}/api/v1/app/artifact/bulk" \
  -H "Authorization: Bearer {API_TOKEN}" \
  -H "x-org: {org_slug}" \
  -H "Content-Type: application/json" \
  -d '{
    "artifact_ids": ["artifact_doc_q1", "artifact_link_q1"]
  }'
```

<Accordion title="Example response">
  ```json theme={null}
  [
    {
      "id": "artifact_doc_q1",
      "state": "Deleted"
    },
    {
      "id": "artifact_link_q1",
      "state": "Deleted"
    }
  ]
  ```
</Accordion>

## Check linked artifacts before modifying

Use this endpoint before changing an artifact when you need to check whether linked artifacts depend on it.

<Accordion title="Endpoint parameters">
  | Type | Name | Required | Notes |
  | - | - | - | - |
  | Query | `created_by` | No | Account ID that created the artifacts to check. |
  | Query | `project_id` | No | Project ID to check for linked artifacts. |
  | Query | `artifact_id` | No | Artifact ID to check for linked artifacts. |
</Accordion>

```bash theme={null}
curl "https://{BASE_URL}/api/v1/app/resource/is-safe-to-modify?project_id={projectID}&artifact_id={artifactID}" \
  -H "Authorization: Bearer {API_TOKEN}" \
  -H "x-org: {org_slug}"
```

<Accordion title="Example response">
  ```json theme={null}
  {
    "has_linked_artifacts": false
  }
  ```
</Accordion>

## Errors and edge cases

* **Artifact error codes**: the `error` field maps to ingest failures:

| `error` value | Meaning |
| - | - |
| `InvalidExtension` | File extension is not supported. |
| `MismatchedType` | File type does not match the declared artifact type. |
| `Malformed` | File is corrupt or unreadable. |
| `Encrypted` | File is password‑protected. |
| `ParsingFailure` | Extractor failed to parse the file. |
| `MaxNodes` | Document is too large/complex for parsing. |
| `NoValidFile` | No valid file was found in the upload. |
| `NoValidNodes` | No parseable content was extracted. |
| `InternalError` | Ingest pipeline failed unexpectedly. |
| `Unknown` | Unclassified ingest failure. |

If `ingest_status` is `Error`, fix the source file and retry or replace the artifact. For integration artifacts, correct the source and sync again.

* **Warnings**: `ingest_warnings` can include values like `BigSize`, `UnprocessableContent`, or `NoContent` to indicate non‑fatal issues.
* **400**: required ownership is missing or invalid, such as sending `project_id` without selecting an organization, or a synchronization is already in progress.
* **401/403**: token missing, insufficient permissions, or `organization_id` combined with `x-org`.
* **404**: artifact, organization, or project not found. A retry payload with ownership that differs from the original artifact is also rejected as not found.
* For files larger than 250 MB, the backend retains only the artifact record with an `UnprocessableContent` warning; it does not store the uploaded bytes or start ingestion.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.