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

# Publish an artifact

> Store an immutable, organization-private HTML case report with provenance and bundled assets.

Store a completed HTML report and its assets. Requires `samples:write` and
`results:read`. Creation is credit-free; organization and author come from
authentication.

`description` is required provenance: summarize the data sources, methods and
limitations. Titles are trimmed to 1 to 200 characters; descriptions to 1 to 10,000
characters. Blank values are rejected.

```bash theme={"dark"}
curl https://app.strandai.com/api/v1/artifacts \
  -H "Authorization: Bearer $STRAND_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Study memo","description":"Public example; manual counts; research use only.","html":"<!doctype html><h1>Study memo</h1><p>Example report.</p>","sample_ids":[],"job_ids":[],"assets":[]}'
```

* `sample_ids` and `job_ids` are optional arrays of up to 100 unique UUIDs each.
  Linked resources must belong to the authenticated organization.
* `html` is the nonempty UTF-8 entry document, stored as `index.html`.
* `assets` accepts up to 128 `{path, content_base64}` objects. Use canonical
  base64 and unique relative paths such as `assets/figure.png`. Path segments
  use ASCII letters, digits, `_`, `-` and `.` (including Zarr
  metadata such as `.zattrs`); dot-only segments `.` and `..` are rejected. Paths are at most 240 characters. Traversal, absolute
  paths, `index.html` and `_strand_bundle.json` are rejected.
* HTML plus decoded assets must fit within **32 MiB**. The application limits
  encoded JSON to **46 MiB**, but deployment proxy limits can be lower. For
  example, a 32 MiB encoded-request edge limit leaves roughly 24 MiB for decoded
  base64 assets, before JSON/HTML overhead. The 32 MiB bundle cap is not a
  guarantee that every deployment accepts a request of that size. Multipart and
  signed-upload flows for larger bundles are not implemented.
* Reference bundled assets using relative URLs; external network resources are
  blocked when the report renders.

A **201** response contains snake\_case metadata, provenance, linked IDs,
auth-derived author, `entry_html_path`, `size_bytes`, `sha256`, `created_at`,
and `url`. The relative in-app URL requires an organization member's signed-in
session, and metadata responses omit HTML and asset bytes.

Invalid input, bundle paths or foreign linked resources return **400**;
oversized encoded JSON returns **413**. A deployment proxy may reject a smaller
request before it reaches this endpoint.

### Python and MCP

```python theme={"dark"}
artifact = client.artifacts.create(
    title="Study memo",
    description="Public example; manual counts; research use only.",
    html="<!doctype html><h1>Study memo</h1>",
)
print(artifact["url"])
```

MCP `create_artifact` accepts the same fields and sends report content through
the tool call. Keep credentials and patient identifiers out of report content.
Artifacts are immutable, with no edit-in-place API. To remove one, use
[Delete an artifact](https://docs.strandai.com/api-reference/endpoint/deleteArtifact.md).


## OpenAPI

````yaml POST /artifacts
openapi: 3.1.0
info:
  title: Strand AI Platform API
  version: v1
  description: >-
    REST surface for uploading WSIs, submitting Lattice inference jobs, and
    streaming results. All endpoints require an API key or Strand AI OAuth
    access token in the `Authorization: Bearer` header.
servers:
  - url: https://app.strandai.com/api/v1
    description: Production
security:
  - ApiKey: []
  - OAuth2: []
paths:
  /artifacts:
    post:
      summary: Publish an HTML artifact
      description: >-
        Publish an immutable org-private HTML report with bundled assets.
        Credit-free. Requires samples:write and results:read. Author and org
        derive from authentication; links must belong to the org. Decoded bundle
        limit 32 MiB; application encoded JSON limit 46 MiB. Deployment proxy
        limits may be lower (for example, a 32 MiB encoded edge limit permits
        roughly 24 MiB of decoded base64 assets before overhead).
        Multipart/signed uploads are not implemented. External network resources
        are blocked when rendered.
      operationId: createArtifact
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateArtifact'
      responses:
        '201':
          description: Created artifact metadata and org-gated URL
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Artifact'
        '400':
          description: Invalid input, bundle or linked sample/job
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Missing or invalid credential
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Insufficient scopes or organization access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '413':
          description: Encoded JSON exceeds 46 MiB
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - ApiKey: []
        - OAuth2:
            - samples:write
            - results:read
components:
  schemas:
    CreateArtifact:
      type: object
      additionalProperties: false
      required:
        - title
        - description
        - html
      properties:
        title:
          type: string
          minLength: 1
          maxLength: 200
          description: Trimmed; must not be blank.
        description:
          type: string
          minLength: 1
          maxLength: 10000
          description: >-
            Required nonblank provenance summary: sources, methods and
            limitations.
        html:
          type: string
          minLength: 1
          description: UTF-8 HTML plus decoded assets must not exceed 32 MiB.
        sample_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 100
          uniqueItems: true
          default: []
        job_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 100
          uniqueItems: true
          default: []
        assets:
          type: array
          maxItems: 128
          default: []
          items:
            type: object
            additionalProperties: false
            required:
              - path
              - content_base64
            properties:
              path:
                type: string
                minLength: 1
                maxLength: 240
                pattern: ^[A-Za-z0-9_.-]+(/[A-Za-z0-9_.-]+)*$
                description: >-
                  Unique relative path; dot-only segments, index.html and
                  _strand_bundle.json are reserved.
              content_base64:
                type: string
                contentEncoding: base64
                description: Canonical base64.
    Artifact:
      type: object
      required:
        - id
        - org_id
        - title
        - description
        - sample_ids
        - job_ids
        - author_type
        - author_id
        - entry_html_path
        - size_bytes
        - sha256
        - created_at
        - url
      properties:
        id:
          type: string
          format: uuid
        org_id:
          type: string
          format: uuid
        title:
          type: string
        description:
          type: string
        sample_ids:
          type: array
          items:
            type: string
            format: uuid
        job_ids:
          type: array
          items:
            type: string
            format: uuid
        author_type:
          type: string
          enum:
            - user
            - agent
        author_id:
          type: string
        entry_html_path:
          type: string
          enum:
            - index.html
        size_bytes:
          type: integer
          minimum: 1
          maximum: 33554432
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        created_at:
          type: string
          format: date-time
        url:
          type: string
          description: Org-gated relative in-app URL /artifacts/{id}, not a public link.
    Error:
      type: object
      required:
        - error
        - message
      properties:
        error:
          type: string
        message:
          type: string
        reason:
          type: string
          nullable: true
        required:
          type: integer
          nullable: true
        retryAfterSeconds:
          type: integer
          nullable: true
  securitySchemes:
    ApiKey:
      type: http
      scheme: bearer
      bearerFormat: sk-strand-XXXXXXXXXXXXXXXXXXXXXXXX
    OAuth2:
      type: oauth2
      description: >-
        Strand AI authorization-code flow with S256 PKCE, explicit organization
        consent, and RFC 8707 resource binding.
      flows:
        authorizationCode:
          authorizationUrl: https://auth.strandai.com/oauth2/auth
          tokenUrl: https://auth.strandai.com/oauth2/token
          scopes:
            samples:read: Read slide metadata and estimates
            samples:write: Upload and change slides
            jobs:read: Read run status
            jobs:write: Start, export, or cancel runs
            results:read: Read and download results
            credits:spend: Reserve and spend organization credits

````

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