---
title: "Add an item: start an upload, or add a web page"
method: POST
path: "/workspaces/{id}/content"
tags: ["content"]
---

# Add an item: start an upload, or add a web page

`POST /workspaces/{id}/content`

## Request

- Base URL: `https://api.swingfactor.ai/v1`
- URL: `https://api.swingfactor.ai/v1/workspaces/{id}/content`
- Auth: HTTP bearer

An upload is created pending, with where its bytes go; it is refused before anything is stored when the kind does not take its type or size. A web page is kept by its address and read in the background — the page already held under that address is returned rather than a second one. Either is refused when the plan does not allow another.

## Path parameters

- `id` string, uuid, required

## Headers

- `Idempotency-Key` string

## Request body

- union
  - object
    - `kind` 'sources', required
    - `origin` 'upload', required
    - `name` string, required
    - `contentType` string, required
    - `size` integer, required
    - `note` string
  - object
    - `kind` 'sources', required
    - `origin` 'web', required
    - `url` string, required
    - `name` string
    - `note` string

## Response `201`

The item, and for an upload where to send its bytes.

- ContentCreated
  - `item` ContentItem, required
    - `id` string, uuid, required
    - `kind` 'sources', required
    - `origin` 'upload' | 'web', required: Where its bytes come from: an upload, or a web page.
    - `name` string, required: A file’s name; a page’s title, or its address until it is read.
    - `note` string, nullable, required: What it is for, in the words of whoever added it.
    - `url` string, nullable, required: A page’s address. Null for an upload.
    - `status` 'pending' | 'ready', required
    - `contentType` string, nullable, required
    - `size` integer, nullable, required: Bytes: as declared while an upload is pending, as stored once ready.
    - `currentVersionId` string, uuid, nullable, required: The version it reads as now.
    - `readStatus` 'waiting' | 'reading' | 'read' | 'no_text' | 'failed' | 'not_read' | 'null', nullable, required: For a kind that is read: how far reading its text has got.
    - `readError` string, nullable, required: Why the last reading came to nothing, in words.
    - `textChars` integer, nullable, required: Characters of text read out.
    - `readAt` string, nullable, required
    - `checkedAt` string, nullable, required: When its origin was last asked whether it changed.
    - `addedBy` string, uuid, nullable, required
    - `addedByName` string, nullable, required: Kept when the account that added it is gone.
    - `addedByActor` string, nullable, required: What added it where no person did: the product, for what its model found.
    - `createdAt` string, required
    - `links` ContentItemLinks, required: Relative /v1 URLs to follow.
      - `self` string, required
      - `workspace` string, required
      - `download` string
      - `complete` string
      - `upload` string
  - `upload` Upload, nullable, required: For an upload: where its bytes go.
    - `url` string, required: Send the bytes here, with these headers. Signed; no token needed.
    - `method` 'PUT', required
    - `headers` object, required
    - `expiresAt` string, required

## Other responses

- `401`: No token, or not a valid one: `unauthorized`.
- `403`: Not an editor.
- `422`: A type, a size, an address or a plan limit refused it.

---

[API](https://skmtc.dev/swingfactor/apis/swingfactor-api.md) · [All operations](https://skmtc.dev/swingfactor/apis/swingfactor-api/llms.txt) · [OpenAPI document](https://skmtc.dev/swingfactor/apis/swingfactor-api/revisions/c2fe881a39c3?raw)
