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

# Upload Files

> Upload 1 to 50 images or videos. Every upload creates a post. Two or more files form one album unless `post-type: individual` is sent.

Upload between 1 and 50 files in one request. Every upload creates a post. Two or more files are grouped into one album post unless you ask for individual posts.

## Headers

| Header | Required | Description |
| - | - | - |
| `relay-key` | Yes | Your relay key, or a [team access key](/authentication#team-access-keys) |
| `post-privacy` | No | `public`, `unlisted` or `private`. Omitted means `private`. Any other value returns `400`. |
| `post-type` | No | `album` (default) or `individual`. Only matters for two or more files. |
| `include-metadata` | No | `true` keeps file metadata. Omitted or `false` strips it. |
| `priority` | No | `false` opts videos out of priority (adaptive) streaming. Omitted or `true` keeps it on, subject to your remaining priority minutes. |

Header values are trimmed and case-insensitive. Boolean headers accept only `true` or `false`; anything else returns `400`.

## Form fields

| Field | Required | Description |
| - | - | - |
| `file` | Yes | The file. Repeat the field for up to 50 files. |
| `title` | No | Up to 30 characters. Longer titles return `400`. |
| `description` | No | Up to 200 characters. Longer descriptions return `400`. |

## Behavior

* **One file:** creates one post. `post-type` is ignored.
* **Two or more files:** creates one album post, or one post per file with `post-type: individual`.
* **Response shape:** when one post is created the body is `{url, post}`, where `url` is the direct URL of the post's first file (`post.files[0].url`). When several posts are created (`individual`), the body is `{posts}`. An album where only one file survived also returns `{url, post}`.
* **`url` and `post.url`:** the top-level `url` is the direct file on `i.snipp.gg`. `post.url` is the share page, `https://snipp.gg/p/{code}`, or `https://{domain}/{code}` when the account has picked another [link domain](/concepts/custom-domains).
* **Private posts:** file URLs are signed and expire after 24 hours. Fetch the post again with [`GET /posts/{code}`](/relay-reference/endpoint/posts/get) for fresh ones.
* **Videos:** `.mp4`, `.mov` and `.mkv` are remuxed to MP4 with `+faststart`, so `.mov` and `.mkv` come back with an `.mp4` name. A file that cannot be remuxed is rejected as corrupt. Uploaded videos get a thumbnail in `files[].thumbnail_url`. See [File Types](/concepts/file-types).
* **Metadata:** stripped by default. PNG, JPG, WebP and GIF are stripped at any size without re-encoding, so pixels are untouched; JPG and WebP keep their orientation and GIF keeps its animation. Videos lose container metadata during the remux.
* **Priority streaming:** eligible videos use adaptive streaming by default and spend [priority minutes](/concepts/plans#priority-minutes). `post.priority` is `true` when a video was queued for it. Minutes are charged after the response; if your budget runs out first, the video falls back to standard quality and the post later reports `priority: false`.
* **Partial failures:** files that fail are listed in `failed`, each with its zero-based `index` and an `error` object. The stored files are still returned with `200`.
* **Every file failed:** a one-file request returns that file's error at the top level, with `413` for `file_too_large`, `500` for `internal` and `400` otherwise. A request with several files returns `400` with type `upload_failed` and the same `failed` array. See [Errors](/concepts/errors#partial-upload-failures).
* **Weekly quota:** a file that would exceed your [weekly usage limit](/concepts/plans#weekly-usage-limit) fails with type `quota_exceeded`, carrying `quota`, `used` and `resets_at`.
* **Size limits:** a file over your plan's per-file limit fails with type `file_too_large`. A request whose declared `Content-Length` is already larger than your weekly quota (or 50 times the per-file limit) is refused with `413` before any file is read.
* **Team keys:** posts are always created `private`, whatever `post-privacy` says, and count against the team's quota. A lapsed team returns `403` with type `forbidden`.
* New posts are scanned automatically. A flagged post is moderated after the response.

## Examples

One file:

```bash theme={null}
curl -X POST "https://relay.snipp.gg/upload" \
  -H "relay-key: YOUR_RELAY_KEY" \
  -H "post-privacy: unlisted" \
  -F "title=my gaming POV" \
  -F "file=@screenshot.png"
```

An album:

```bash theme={null}
curl -X POST "https://relay.snipp.gg/upload" \
  -H "relay-key: YOUR_RELAY_KEY" \
  -H "post-privacy: public" \
  -F "title=Match highlights" \
  -F "file=@photo1.png" \
  -F "file=@photo2.png"
```

One post per file:

```bash theme={null}
curl -X POST "https://relay.snipp.gg/upload" \
  -H "relay-key: YOUR_RELAY_KEY" \
  -H "post-type: individual" \
  -F "file=@image1.png" \
  -F "file=@image2.png" \
  -F "file=@image3.png"
```

## Responses

One file:

```json theme={null}
{
  "url": "https://i.snipp.gg/123456789012345678/a1b2c3d4e5f6789012345678abcdef01.png",
  "post": {
    "code": "AbCd1234",
    "url": "https://snipp.gg/p/AbCd1234",
    "title": "my gaming POV",
    "description": null,
    "privacy": "unlisted",
    "created_at": "2026-10-01T09:15:27.204Z",
    "view_count": 0,
    "like_count": 0,
    "comment_count": 0,
    "priority": false,
    "file_count": 1,
    "files": [
      {
        "name": "a1b2c3d4e5f6789012345678abcdef01.png",
        "url": "https://i.snipp.gg/123456789012345678/a1b2c3d4e5f6789012345678abcdef01.png",
        "size": 2487312,
        "mime_type": "image/png",
        "width": 1920,
        "height": 1080,
        "thumbnail_url": null
      }
    ],
    "team_id": null,
    "author": {
      "id": "123456789012345678",
      "username": "playerone",
      "nickname": "Player One",
      "avatar": "https://i.snipp.gg/avatars/123456789012345678/7e1f0a2b3c4d5e6f708192a3b4c5d6e7.png",
      "verified": false,
      "plan": "plus"
    },
    "liked": false,
    "moderated": false,
    "restricted": false
  }
}
```

A private upload. The file URLs are signed:

```json theme={null}
{
  "url": "https://i.snipp.gg/123456789012345678/a1b2c3d4e5f6789012345678abcdef01.png?e=1790035200&s=9f2c4b7d1e8a3f6c0b5d2e9a7c4f1b8e3d6a0c9f2b5e8d1a4c7f0b3e6d9a2c5f",
  "post": {
    "code": "AbCd1234",
    "url": "https://snipp.gg/p/AbCd1234",
    "title": null,
    "description": null,
    "privacy": "private",
    "created_at": "2026-10-01T09:15:27.204Z",
    "view_count": 0,
    "like_count": 0,
    "comment_count": 0,
    "priority": false,
    "file_count": 1,
    "files": [
      {
        "name": "a1b2c3d4e5f6789012345678abcdef01.png",
        "url": "https://i.snipp.gg/123456789012345678/a1b2c3d4e5f6789012345678abcdef01.png?e=1790035200&s=9f2c4b7d1e8a3f6c0b5d2e9a7c4f1b8e3d6a0c9f2b5e8d1a4c7f0b3e6d9a2c5f",
        "size": 2487312,
        "mime_type": "image/png",
        "width": 1920,
        "height": 1080,
        "thumbnail_url": null
      }
    ],
    "team_id": null,
    "author": {
      "id": "123456789012345678",
      "username": "playerone",
      "nickname": "Player One",
      "avatar": "https://i.snipp.gg/avatars/123456789012345678/7e1f0a2b3c4d5e6f708192a3b4c5d6e7.png",
      "verified": false,
      "plan": "plus"
    },
    "liked": false,
    "moderated": false,
    "restricted": false
  }
}
```

An album:

```json theme={null}
{
  "url": "https://i.snipp.gg/123456789012345678/a1b2c3d4e5f6789012345678abcdef01.png",
  "post": {
    "code": "AlBm5678",
    "url": "https://snipp.gg/p/AlBm5678",
    "title": "Match highlights",
    "description": null,
    "privacy": "public",
    "created_at": "2026-10-01T09:15:27.204Z",
    "view_count": 0,
    "like_count": 0,
    "comment_count": 0,
    "priority": false,
    "file_count": 2,
    "files": [
      {
        "name": "a1b2c3d4e5f6789012345678abcdef01.png",
        "url": "https://i.snipp.gg/123456789012345678/a1b2c3d4e5f6789012345678abcdef01.png",
        "size": 2487312,
        "mime_type": "image/png",
        "width": 1920,
        "height": 1080,
        "thumbnail_url": null
      },
      {
        "name": "b2c3d4e5f6789012345678abcdef0102.png",
        "url": "https://i.snipp.gg/123456789012345678/b2c3d4e5f6789012345678abcdef0102.png",
        "size": 1843210,
        "mime_type": "image/png",
        "width": 1280,
        "height": 720,
        "thumbnail_url": null
      }
    ],
    "team_id": null,
    "author": {
      "id": "123456789012345678",
      "username": "playerone",
      "nickname": "Player One",
      "avatar": "https://i.snipp.gg/avatars/123456789012345678/7e1f0a2b3c4d5e6f708192a3b4c5d6e7.png",
      "verified": false,
      "plan": "plus"
    },
    "liked": false,
    "moderated": false,
    "restricted": false
  }
}
```

Individual posts, where the third file went over the weekly quota:

```json theme={null}
{
  "posts": [
    {
      "code": "InDv0001",
      "url": "https://snipp.gg/p/InDv0001",
      "title": null,
      "description": null,
      "privacy": "public",
      "created_at": "2026-10-01T09:15:27.204Z",
      "view_count": 0,
      "like_count": 0,
      "comment_count": 0,
      "priority": false,
      "file_count": 1,
      "files": [
        {
          "name": "a1b2c3d4e5f6789012345678abcdef01.png",
          "url": "https://i.snipp.gg/123456789012345678/a1b2c3d4e5f6789012345678abcdef01.png",
          "size": 2487312,
          "mime_type": "image/png",
          "width": 1920,
          "height": 1080,
          "thumbnail_url": null
        }
      ],
      "team_id": null,
      "author": {
        "id": "123456789012345678",
        "username": "playerone",
        "nickname": "Player One",
        "avatar": "https://i.snipp.gg/avatars/123456789012345678/7e1f0a2b3c4d5e6f708192a3b4c5d6e7.png",
        "verified": false,
        "plan": "plus"
      },
      "liked": false,
      "moderated": false,
      "restricted": false
    },
    {
      "code": "InDv0002",
      "url": "https://snipp.gg/p/InDv0002",
      "title": null,
      "description": null,
      "privacy": "public",
      "created_at": "2026-10-01T09:15:27.204Z",
      "view_count": 0,
      "like_count": 0,
      "comment_count": 0,
      "priority": false,
      "file_count": 1,
      "files": [
        {
          "name": "b2c3d4e5f6789012345678abcdef0102.png",
          "url": "https://i.snipp.gg/123456789012345678/b2c3d4e5f6789012345678abcdef0102.png",
          "size": 1843210,
          "mime_type": "image/png",
          "width": 1280,
          "height": 720,
          "thumbnail_url": null
        }
      ],
      "team_id": null,
      "author": {
        "id": "123456789012345678",
        "username": "playerone",
        "nickname": "Player One",
        "avatar": "https://i.snipp.gg/avatars/123456789012345678/7e1f0a2b3c4d5e6f708192a3b4c5d6e7.png",
        "verified": false,
        "plan": "plus"
      },
      "liked": false,
      "moderated": false,
      "restricted": false
    }
  ],
  "failed": [
    {
      "index": 2,
      "error": {
        "type": "quota_exceeded",
        "message": "Weekly usage limit exceeded.",
        "quota": 21474836480,
        "used": 21470000000,
        "resets_at": "2026-10-04T16:20:00.000Z"
      }
    }
  ]
}
```

Every file failed:

```json theme={null}
{
  "error": {
    "type": "upload_failed",
    "message": "All files failed to upload.",
    "failed": [
      {
        "index": 0,
        "error": {
          "type": "unsupported_type",
          "message": "Unsupported file type."
        }
      },
      {
        "index": 1,
        "error": {
          "type": "file_too_large",
          "message": "File size exceeds the 50 MB limit."
        }
      }
    ]
  }
}
```

## Errors

| Status | Type | When |
| - | - | - |
| `400` | `invalid_request` | Bad header value, no file, more than 50 files, title or description too long, or a corrupt video |
| `400` | `unsupported_type` | The only file is not a supported type |
| `400` | `quota_exceeded` | The only file would exceed your weekly quota |
| `400` | `upload_failed` | Every file of a multi-file request failed |
| `401` | `unauthorized` | Missing or invalid key |
| `403` | `suspended` | Your account, or the team owner's, is suspended |
| `403` | `forbidden` | The team's subscription has lapsed |
| `413` | `file_too_large` | The only file is over your limit, or the declared request size is |
| `429` | `rate_limited` | More than 20 uploads in 30 seconds |
| `500` | `internal` | The upload could not be saved |


## OpenAPI

````yaml relay-reference/openapi.json POST /upload
openapi: 3.0.0
info:
  title: Snipp.gg Relay API
  description: >-
    First-party Snipp API for the full user experience: uploads, posts,
    discover, likes, comments, notifications, blocks and profile management.
  version: 3.0.0
servers:
  - url: https://relay.snipp.gg
    description: Default. Load-balanced across regions. No upload cap.
  - url: https://eu-west-1.relay.snipp.gg
    description: EU West regional endpoint. Pins uploads and storage to EU West.
  - url: https://us-west-1.relay.snipp.gg
    description: US West regional endpoint. Pins uploads and storage to US West.
  - url: https://pulsar.snipp.gg
    description: Alternative host. Capped at 100 MB per upload.
security:
  - relayKeyAuth: []
paths:
  /upload:
    post:
      summary: Upload Files
      description: >-
        Upload 1 to 50 images or videos. Every upload creates a post. Two or
        more files form one album unless `post-type: individual` is sent.
      operationId: upload
      parameters:
        - name: post-privacy
          in: header
          required: false
          description: '`public`, `unlisted` or `private`. Omitted means `private`.'
          schema:
            type: string
            enum:
              - public
              - unlisted
              - private
            default: private
        - name: post-type
          in: header
          required: false
          description: '`album` or `individual`. Only matters for two or more files.'
          schema:
            type: string
            enum:
              - album
              - individual
            default: album
        - $ref: '#/components/parameters/IncludeMetadata'
        - $ref: '#/components/parameters/Priority'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: array
                  items:
                    type: string
                    format: binary
                  description: 1 to 50 files. Repeat the `file` field.
                title:
                  type: string
                  maxLength: 30
                  description: Up to 30 characters.
                description:
                  type: string
                  maxLength: 200
                  description: Up to 200 characters.
              required:
                - file
      responses:
        '200':
          description: Success
          headers:
            request-id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    properties:
                      url:
                        type: string
                        description: Direct URL of the first file (`post.files[0].url`).
                      post:
                        $ref: '#/components/schemas/Post'
                      failed:
                        type: array
                        items:
                          $ref: '#/components/schemas/FailedFile'
                    required:
                      - url
                      - post
                    description: One post was created.
                  - type: object
                    properties:
                      posts:
                        type: array
                        items:
                          $ref: '#/components/schemas/Post'
                      failed:
                        type: array
                        items:
                          $ref: '#/components/schemas/FailedFile'
                    required:
                      - posts
                    description: 'Several posts were created (`post-type: individual`).'
              examples:
                single:
                  summary: One file
                  value:
                    url: >-
                      https://i.snipp.gg/123456789012345678/a1b2c3d4e5f6789012345678abcdef01.png
                    post:
                      code: AbCd1234
                      url: https://snipp.gg/p/AbCd1234
                      title: my gaming POV
                      description: null
                      privacy: unlisted
                      created_at: '2026-10-01T09:15:27.204Z'
                      view_count: 0
                      like_count: 0
                      comment_count: 0
                      priority: false
                      file_count: 1
                      files:
                        - name: a1b2c3d4e5f6789012345678abcdef01.png
                          url: >-
                            https://i.snipp.gg/123456789012345678/a1b2c3d4e5f6789012345678abcdef01.png
                          size: 2487312
                          mime_type: image/png
                          width: 1920
                          height: 1080
                          thumbnail_url: null
                      team_id: null
                      author:
                        id: '123456789012345678'
                        username: playerone
                        nickname: Player One
                        avatar: >-
                          https://i.snipp.gg/avatars/123456789012345678/7e1f0a2b3c4d5e6f708192a3b4c5d6e7.png
                        verified: false
                        plan: plus
                      liked: false
                      moderated: false
                      restricted: false
                album:
                  summary: Album
                  value:
                    url: >-
                      https://i.snipp.gg/123456789012345678/a1b2c3d4e5f6789012345678abcdef01.png
                    post:
                      code: AlBm5678
                      url: https://snipp.gg/p/AlBm5678
                      title: Match highlights
                      description: null
                      privacy: public
                      created_at: '2026-10-01T09:15:27.204Z'
                      view_count: 0
                      like_count: 0
                      comment_count: 0
                      priority: false
                      file_count: 2
                      files:
                        - name: a1b2c3d4e5f6789012345678abcdef01.png
                          url: >-
                            https://i.snipp.gg/123456789012345678/a1b2c3d4e5f6789012345678abcdef01.png
                          size: 2487312
                          mime_type: image/png
                          width: 1920
                          height: 1080
                          thumbnail_url: null
                        - name: b2c3d4e5f6789012345678abcdef0102.png
                          url: >-
                            https://i.snipp.gg/123456789012345678/b2c3d4e5f6789012345678abcdef0102.png
                          size: 1843210
                          mime_type: image/png
                          width: 1280
                          height: 720
                          thumbnail_url: null
                      team_id: null
                      author:
                        id: '123456789012345678'
                        username: playerone
                        nickname: Player One
                        avatar: >-
                          https://i.snipp.gg/avatars/123456789012345678/7e1f0a2b3c4d5e6f708192a3b4c5d6e7.png
                        verified: false
                        plan: plus
                      liked: false
                      moderated: false
                      restricted: false
                individual:
                  summary: Individual posts with a failed file
                  value:
                    posts:
                      - code: InDv0001
                        url: https://snipp.gg/p/InDv0001
                        title: null
                        description: null
                        privacy: public
                        created_at: '2026-10-01T09:15:27.204Z'
                        view_count: 0
                        like_count: 0
                        comment_count: 0
                        priority: false
                        file_count: 1
                        files:
                          - name: a1b2c3d4e5f6789012345678abcdef01.png
                            url: >-
                              https://i.snipp.gg/123456789012345678/a1b2c3d4e5f6789012345678abcdef01.png
                            size: 2487312
                            mime_type: image/png
                            width: 1920
                            height: 1080
                            thumbnail_url: null
                        team_id: null
                        author:
                          id: '123456789012345678'
                          username: playerone
                          nickname: Player One
                          avatar: >-
                            https://i.snipp.gg/avatars/123456789012345678/7e1f0a2b3c4d5e6f708192a3b4c5d6e7.png
                          verified: false
                          plan: plus
                        liked: false
                        moderated: false
                        restricted: false
                      - code: InDv0002
                        url: https://snipp.gg/p/InDv0002
                        title: null
                        description: null
                        privacy: public
                        created_at: '2026-10-01T09:15:27.204Z'
                        view_count: 0
                        like_count: 0
                        comment_count: 0
                        priority: false
                        file_count: 1
                        files:
                          - name: b2c3d4e5f6789012345678abcdef0102.png
                            url: >-
                              https://i.snipp.gg/123456789012345678/b2c3d4e5f6789012345678abcdef0102.png
                            size: 1843210
                            mime_type: image/png
                            width: 1280
                            height: 720
                            thumbnail_url: null
                        team_id: null
                        author:
                          id: '123456789012345678'
                          username: playerone
                          nickname: Player One
                          avatar: >-
                            https://i.snipp.gg/avatars/123456789012345678/7e1f0a2b3c4d5e6f708192a3b4c5d6e7.png
                          verified: false
                          plan: plus
                        liked: false
                        moderated: false
                        restricted: false
                    failed:
                      - index: 2
                        error:
                          type: quota_exceeded
                          message: Weekly usage limit exceeded.
                          quota: 21474836480
                          used: 21470000000
                          resets_at: '2026-10-04T16:20:00.000Z'
        '400':
          $ref: '#/components/responses/E400'
        '401':
          $ref: '#/components/responses/E401'
        '403':
          $ref: '#/components/responses/E403'
        '405':
          $ref: '#/components/responses/E405'
        '413':
          $ref: '#/components/responses/E413'
        '429':
          $ref: '#/components/responses/E429'
        '500':
          $ref: '#/components/responses/E500'
components:
  parameters:
    IncludeMetadata:
      name: include-metadata
      in: header
      required: false
      description: '`true` keeps file metadata. Omitted or `false` strips it.'
      schema:
        type: boolean
        default: false
    Priority:
      name: priority
      in: header
      required: false
      description: '`false` opts videos out of priority (adaptive) streaming.'
      schema:
        type: boolean
        default: true
  headers:
    RequestId:
      description: Unique ID for the request. Include it when contacting support.
      schema:
        type: string
        format: uuid
  schemas:
    Post:
      type: object
      properties:
        code:
          type: string
          description: Share code.
        url:
          type: string
          description: >-
            Share page, `https://snipp.gg/p/{code}`. When the account has picked
            another link domain, `https://{domain}/{code}` instead.
        title:
          type: string
          nullable: true
        description:
          type: string
          nullable: true
        privacy:
          type: string
          enum:
            - public
            - unlisted
            - private
        created_at:
          type: string
          format: date-time
        view_count:
          type: integer
        like_count:
          type: integer
          description: '`null` on team posts.'
          nullable: true
        comment_count:
          type: integer
        priority:
          type: boolean
          description: At least one video is on priority (adaptive) streaming.
        file_count:
          type: integer
        files:
          type: array
          items:
            $ref: '#/components/schemas/File'
        team_id:
          type: string
          description: Team ID for team posts, otherwise `null`.
          nullable: true
        author:
          $ref: '#/components/schemas/UserRef'
          nullable: true
        liked:
          type: boolean
          description: You liked the post. `null` on team posts.
          nullable: true
        moderated:
          type: boolean
          description: Owner only. Omitted for everyone else.
        restricted:
          type: boolean
          description: Owner only. Omitted for everyone else.
        access:
          type: array
          items:
            allOf:
              - $ref: '#/components/schemas/UserRef'
              - type: object
                properties:
                  suspended:
                    type: boolean
                    description: >-
                      True while that account is suspended. Show the entry
                      dimmed; nothing about the access changes and it returns to
                      normal on unsuspension.
                required:
                  - suspended
          description: >-
            Owner of a personal post only, on `GET` and `PATCH /posts/{code}`:
            users who can open it while private.
      required:
        - code
        - url
        - title
        - description
        - privacy
        - created_at
        - view_count
        - like_count
        - comment_count
        - priority
        - file_count
        - files
        - team_id
        - author
        - liked
    FailedFile:
      type: object
      properties:
        index:
          type: integer
          description: Zero-based position of the file in the request.
        error:
          $ref: '#/components/schemas/ErrorDetail'
      required:
        - index
        - error
      description: >-
        A file that was not stored. `error` has the same shape as a top-level
        error.
    File:
      type: object
      properties:
        name:
          type: string
          description: 'Stored file name: 32 hex characters plus an extension.'
        url:
          type: string
          description: Direct file URL. Signed for 24 hours on private posts.
        size:
          type: integer
          description: Bytes.
          nullable: true
        mime_type:
          type: string
          nullable: true
        width:
          type: integer
          nullable: true
        height:
          type: integer
          nullable: true
        thumbnail_url:
          type: string
          description: Video thumbnail URL, or `null`.
          nullable: true
      required:
        - name
        - url
        - size
        - mime_type
        - width
        - height
        - thumbnail_url
    UserRef:
      type: object
      properties:
        id:
          type: string
          description: User ID (snowflake).
        username:
          type: string
          nullable: true
        nickname:
          type: string
          nullable: true
        avatar:
          type: string
          description: Avatar URL. Falls back to `https://cdn.snipp.gg/avatar.png`.
        verified:
          type: boolean
        plan:
          $ref: '#/components/schemas/Plan'
      required:
        - id
        - username
        - nickname
        - avatar
        - verified
        - plan
      description: A user embedded inside another resource.
    ErrorDetail:
      type: object
      properties:
        type:
          $ref: '#/components/schemas/ErrorType'
        message:
          type: string
          description: Human-readable sentence. Do not match on it; use `type`.
        username:
          type: string
          description: >-
            `suspended` on `GET /users/{id}` only: the suspended user's
            username.
        quota:
          type: integer
          description: >-
            `quota_exceeded` only: the limit, in bytes for the weekly quota or
            minutes for priority minutes.
        used:
          type: integer
          description: >-
            `quota_exceeded` only: usage in the current window, in the same unit
            as `quota`.
        resets_at:
          type: string
          format: date-time
          description: '`quota_exceeded` only: when the window resets.'
          nullable: true
        failed:
          type: array
          items:
            $ref: '#/components/schemas/FailedFile'
          description: '`upload_failed` only: one entry per file.'
      required:
        - type
        - message
    Error:
      type: object
      properties:
        error:
          $ref: '#/components/schemas/ErrorDetail'
      required:
        - error
      description: Every non-2xx response has this body.
    Plan:
      type: string
      enum:
        - free
        - plus
        - ultra
    ErrorType:
      type: string
      enum:
        - invalid_request
        - unauthorized
        - forbidden
        - suspended
        - blocked
        - moderated
        - plan_required
        - not_found
        - method_not_allowed
        - file_too_large
        - unsupported_type
        - quota_exceeded
        - rate_limited
        - upload_failed
        - internal
        - unavailable
      description: Machine-readable error category. See [Errors](/concepts/errors).
  responses:
    E400:
      description: Invalid request
      headers:
        request-id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    E401:
      description: Missing or invalid key
      headers:
        request-id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    E403:
      description: Not allowed
      headers:
        request-id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    E405:
      description: Method not allowed
      headers:
        request-id:
          $ref: '#/components/headers/RequestId'
        Allow:
          description: Methods this path accepts.
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    E413:
      description: File too large
      headers:
        request-id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    E429:
      description: Rate limited
      headers:
        request-id:
          $ref: '#/components/headers/RequestId'
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    E500:
      description: Internal error
      headers:
        request-id:
          $ref: '#/components/headers/RequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    relayKeyAuth:
      type: apiKey
      in: header
      name: relay-key
      description: Your relay key from snipp.gg/settings/relay

````

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