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

# Share an image

> Get a view-only public link to an image.

Anyone with the returned `url` can open the image in a browser, without an
account, with its latest cell outlines and counts: what your lab sees now,
so later results show up on the same link. Nothing on the page edits the
image, and downloading from it asks the visitor to sign in.

Idempotent: an image has at most one live link, so sharing it again returns
the same share. After `DELETE /shares/{share_id}`, sharing again makes a new
link. An image outside your organization returns `404`.



## OpenAPI

````yaml /api-reference/openapi.json post /api/v1/shares
openapi: 3.1.0
info:
  title: HalfPage API
  description: >
    The **HalfPage API** runs cell segmentation on your microscopy images

    programmatically. Upload an image, run a prediction, and export the

    resulting cell masks, ROIs, and measurements.


    ## Base URL


    ```

    https://api.halfpagetechnologies.com/backend/api/v1

    ```


    Every path in this reference is relative to that base URL. A staging
    environment

    is available at
    `https://staging-api.halfpagetechnologies.com/backend/api/v1`.


    ## Authentication


    Authenticate every request with an API key in the `Authorization` header as
    a

    bearer token:


    ```

    Authorization: Bearer hp_live_xxxxxxxxxxxxxxxxxxxxxxxx

    ```


    Create and manage keys from the **API Keys** section of the HalfPage
    dashboard.

    Keys cannot be minted through the API. A key is scoped to the organization
    that

    owns it; every resource you create or read is confined to that organization.

    Requests without a valid key receive `401`; a valid key used against an
    endpoint

    outside the public product surface receives `403`.


    ## Core workflow


    Three steps (**upload, predict, export**) plus a model list to choose from.

    Segmentation runs asynchronously on GPU workers, so step 2 is poll-based:


    1. **Upload an image** (`POST /upload`) as `multipart/form-data` with a
    `file`
       part. One call: the image record is created for you and the response returns
       it already `ready`, with the `image.id` for the next step.
       *(Large file or flaky connection? POST the same endpoint as
       `application/json` with `{"name": ..., "size": ...}` instead. You get back
       presigned part URLs. PUT the chunks, call
       `POST /upload/{image_id}/complete`, then poll `GET /upload/{image_id}` until
       `upload_status` is `ready`.)*
    2. **Pick a model** (`GET /models`) and **run a prediction** (`POST
    /predict`)
       with the `image_id` and a `model_id`. That returns a `prediction_id`; poll
       `GET /predict/{prediction_id}` until `status` is `SUCCEEDED`. The response
       then carries the `cell_count` detected and the `channel` it ran on.
    3. **Export** the result as an overlay PNG
       (`GET /export/{image_id}/overlay.png`, plus `?channel=` for a result on one
       channel of a multiplex image), CSV measurements
       (`.../measurements.csv`), GeoJSON ROIs (`.../rois.geojson`), or an ImageJ ROI
       archive (`.../rois.zip`). The overlay PNG is a presentation RGB image, not a
       preservation of original TIFF bit depth or scientific metadata.

    ## Quotas


    Uploads and analyses are metered against your plan. Exceeding your image

    storage cap or monthly analysis cap returns `402` with a human-readable

    `detail` explaining the limit. Upgrade your plan to raise it.
  version: 1.1.0
servers:
  - url: https://api.halfpagetechnologies.com/backend
    description: Production
  - url: https://staging-api.halfpagetechnologies.com/backend
    description: Staging
security: []
tags:
  - name: upload
    description: >-
      Get microscopy images into HalfPage, and manage them once they are there.
      `POST /upload` is the only way in and covers both modes: send
      `multipart/form-data` with a `file` part to upload in one request (the
      image comes back `ready`), or send `application/json` with `{name, size}`
      to open a resumable upload and get presigned part URLs back. Resumable
      uploads finish with `complete` (no ETag bookkeeping needed) and are polled
      until `ready`.
  - name: predict
    description: >-
      Run segmentation on a ready image and poll it to completion. `POST
      /predict` queues the run on a GPU worker and returns a `prediction_id`;
      `GET /predict/{prediction_id}` reports progress and, once `SUCCEEDED`, the
      cell count of the result.
  - name: export
    description: >-
      Download an image's result, by its `image_id` and `channel`, as a
      presentation overlay PNG, a CSV of per-cell measurements, a GeoJSON of ROI
      polygons, or a ZIP of ImageJ-compatible ROIs. The CSV endpoint accepts a
      `columns` parameter to narrow the output to the measurements you care
      about.
  - name: models
    description: >-
      List the segmentation models available to your organization (the shared
      public base models such as `Generalist`, plus any custom models trained in
      the dashboard) to choose a `model_id` for a prediction.
  - name: shares
    description: >-
      Share an image as a view-only public link. `POST /shares` returns a `url`
      that anyone can open in a browser, no account needed, to see the image
      with its latest cell outlines and counts. Links are revocable and count
      their views; downloading from a shared page asks the visitor to sign in.
paths:
  /api/v1/shares:
    post:
      tags:
        - shares
      summary: Share an image
      description: >-
        Get a view-only public link to an image.


        Anyone with the returned `url` can open the image in a browser, without
        an

        account, with its latest cell outlines and counts: what your lab sees
        now,

        so later results show up on the same link. Nothing on the page edits the

        image, and downloading from it asks the visitor to sign in.


        Idempotent: an image has at most one live link, so sharing it again
        returns

        the same share. After `DELETE /shares/{share_id}`, sharing again makes a
        new

        link. An image outside your organization returns `404`.
      operationId: create_share_api_v1_shares_post
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateShareRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ShareResponse'
        '401':
          description: >-
            Missing or invalid credentials. Supply a valid `Authorization:
            Bearer hp_live_...` API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                detail: Requires authentication
        '404':
          description: The resource does not exist, or is not in your organization.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                detail: Image with id 3fa85f64-5717-4562-b3fc-2c963f66afa6 not found
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
        - HTTPBearer: []
components:
  schemas:
    CreateShareRequest:
      properties:
        image_id:
          type: string
          title: Image Id
          examples:
            - aB3dE5fG
      type: object
      required:
        - image_id
      title: CreateShareRequest
      description: Share one image, the `image_id` an upload returns.
    ShareResponse:
      properties:
        id:
          type: string
          format: uuid
          title: Id
        image_id:
          type: string
          title: Image Id
        access:
          $ref: '#/components/schemas/ShareAudience'
          description: Who the share reaches. Always `anyone_with_link` today.
        role:
          $ref: '#/components/schemas/ShareRole'
          description: >-
            What they can do. Always `viewer` today: shared images are
            read-only.
        url:
          anyOf:
            - type: string
            - type: 'null'
          title: Url
          description: >-
            The link to send, for `anyone_with_link` shares. Anyone holding it
            can view.
        view_count:
          type: integer
          title: View Count
          description: How many times the link has been opened.
        last_viewed_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Last Viewed At
        created_at:
          type: string
          format: date-time
          title: Created At
        revoked_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Revoked At
          description: When the share was turned off. A revoked link no longer opens.
      type: object
      required:
        - id
        - image_id
        - access
        - role
        - view_count
        - created_at
      title: ShareResponse
      description: |-
        A share of one image. `access` says who it reaches and `role` what they
        can do; `url` is the link to send.
      examples:
        - access: anyone_with_link
          created_at: '2026-07-01T12:05:00Z'
          id: 5b1f0c4e-2d3a-4e5f-9a8b-7c6d5e4f3a2b
          image_id: aB3dE5fG
          last_viewed_at: '2026-07-02T09:30:00Z'
          role: viewer
          url: >-
            https://www.halfpagetechnologies.com/aB3dE5fG?share=uAgn3l8EOJxQXvpIF3G-X3K7c3ziqIAP
          view_count: 3
    ErrorResponse:
      properties:
        detail:
          type: string
          title: Detail
          examples:
            - Job with id 11111111-1111-1111-1111-111111111111 not found
      type: object
      required:
        - detail
      title: ErrorResponse
      description: |-
        The body returned for a handled error: a single human-readable
        ``detail`` string.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    ShareAudience:
      type: string
      enum:
        - anyone_with_link
        - user
      title: ShareAudience
    ShareRole:
      type: string
      enum:
        - viewer
        - editor
      title: ShareRole
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
  securitySchemes:
    HTTPBearer:
      type: http
      scheme: bearer

````

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