---
title: "Get a ticket to attach a file to a species"
method: POST
path: "/api/v2/species/{id}/files"
tags: ["Species"]
---

# Get a ticket to attach a file to a species

`POST /api/v2/species/{id}/files`

## Request

- Base URL: `https://www.onlyworlds.com`
- URL: `https://www.onlyworlds.com/api/v2/species/{id}/files`
- Auth: API key in header `API-Key` and API key in header `API-Pin`

A write key and its PIN that may change the element (the write rule of PATCH; an agent seat answers as its sponsor). Body: the file's name, kind and size, and an optional label. Returns a single-use ticket in the image lane's shape with kind `file`: send the bytes to upload_url with it. The file is listed once the upload host has checked and stored it. Kinds: text (txt, md, json, csv, yaml, toml), pdf, and zip only as a world's own bundle. At most 25 MB a file; a world holds 250 MB of files; 200 tickets a world a day. This route takes no Idempotency-Key: the single-use ticket is the idempotency (a second POST is a second ticket). Files on elements answer only where the server has them switched on; elsewhere every files route is a 404.

## Path parameters

- `id` string, uuid, required

## Headers

- `X-OW-Agent` string

## Request body

- object
  - `name` string, required: The file's name, ending in its kind's extension (.yml and .markdown are taken too).
  - `kind` 'pdf' | 'txt' | 'md' | 'json' | 'csv' | 'yaml' | 'toml' | 'zip', required
  - `size` integer, required: Bytes.
  - `label` string, nullable

## Response `201`

A ticket for one file upload. Cache-Control: no-store.

- object: The image lane's ticket shape, with kind `file` and the file's id.
  - `ticket` string, required: Opaque to clients: send it to upload_url as Authorization: Bearer <ticket>, the file's raw bytes as the body.
  - `upload_url` string, required
  - `prefix` string, required: w/<world_id>/<element_id>/
  - `key` string, required: The object key the file lands under.
  - `max_bytes` integer, required: The most this ticket accepts: 25 MB, or what the world has left, whichever is smaller.
  - `exp` integer, required: Unix seconds after which the ticket is refused (10 minutes).
  - `uses` 1, required
  - `issued_to` object, required
    - `account` string, uuid, nullable, required
    - `membership` string, uuid, nullable, required
  - `kind` 'file', required
  - `file_id` string, uuid, required

## Other responses

- `401`: Missing, invalid or revoked credential, or a wrong PIN (authentication_error; code key_revoked for a revoked key, invalid_credentials otherwise).
- `403`: The credential is valid but lacks the scope: a read key on a write route (permission_error). Or a contributor or guest key changed, replaced, relinked or deleted an element someone else created (code not_author); those members change only their own, and, for an agent seat the owner gave a Character, that Character (never deleting it). Or the world's files have no room for this one (code files_full, type permission_error); the message gives the world's use, its cap and this file's size.
- `404`: Not found in this world (not_found).
- `413`: The file is over 25 MB (code file_too_large, type invalid_request, param size); the message gives both sizes.
- `422`: The body is not {name, kind, size, label?}: an unknown kind (the message names the kinds and, for a Word or spreadsheet file, what to export it as), a name without its kind's extension, a size that is not a whole number of bytes, or a label over 80 characters (invalid_request; `param` names it).
- `429`: Too many failed PIN attempts (rate_limited), or this world's daily file tickets are used up (code quota_exceeded). Both carry Retry-After. Or too many requests: over the request budget (code too_many_requests, type rate_limited): 300 requests a minute per key or account token, 60 a minute per address for a request with neither. Retry after the Retry-After header's seconds.
- `503`: The server is busy: every request slot stayed full for 10 s (code server_busy, type api_error). Retry after the Retry-After header's seconds.

## Changes

- **2026-10-20** `78df39c4c62e`: 7 warning
  - added the new `known_of_not_writable` enum value to the `error/code` response property for the response status `401`
  - added the new `known_of_not_writable` enum value to the `error/code` response property for the response status `403`
  - added the new `known_of_not_writable` enum value to the `error/code` response property for the response status `404`
  - added the new `known_of_not_writable` enum value to the `error/code` response property for the response status `413`
  - …3 more
- **2026-10-20** `4dd5b1cd0687`: 14 warning
  - added the new `character_taken` enum value to the `error/code` response property for the response status `401`
  - added the new `character_taken` enum value to the `error/code` response property for the response status `403`
  - added the new `character_taken` enum value to the `error/code` response property for the response status `404`
  - added the new `character_taken` enum value to the `error/code` response property for the response status `413`
  - …10 more

[Operation history](https://skmtc.dev/onlyworlds/apis/onlyworlds-api/changes/api/v2/species/:id/files/post.md)

---

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