neurall-io Files API

Input uploads for v3 generations

Operations 2

POST /v3/files/upload Upload Files #
POST /v3/files/upload-url Create an Upload URL #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/neurall-io:neurall-io-files-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

neurall-io-files-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Neurall API (v3) Files API
  version: 1.0.0
  description: 'The public v3 surface: /v3/generations for async generations that produce a content asset, /v3/voices for the voice catalog and your own cloned voices, plus file uploads, per-feature pricing, read-only templates, and signed webhooks. Authenticate every call with an API key in the Authorization header. This document is machine-readable at https://api.neurall.io/v3/openapi.json (import it into Postman, or generate a client).'
servers:
- url: https://api.neurall.io
tags:
- name: Files
  description: Input uploads for v3 generations
paths:
  /v3/files/upload:
    post:
      summary: Upload Files
      description: 'Turns a local file into a file id: `args` fields like `image` and `audio` take these ids, never a URL or base64. Call this first, then generate.


        Send `multipart/form-data` with a `files` field: up to 10 files, 30 MB each; images, audio, video or documents (PDF, ZIP, text, JSON). Uploading is permissive on purpose; each feature checks its own limits at generation time, so see that feature''s docs for what it accepts.


        An upload is deleted 24 hours after it lands. Keep the original on your side and upload it again when you need it later.'
      security:
      - ApiKeyAuth: []
      tags:
      - Files
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                files:
                  type: array
                  description: One or more files, all under the same `files` field name. Up to 10 per request, 30 MB each; over either limit answers 400.
                  items:
                    type: string
                    format: binary
              required:
              - files
      responses:
        '200':
          description: The uploaded file ids
          content:
            application/json:
              schema:
                type: object
                properties:
                  files:
                    type: array
                    description: One entry per uploaded file, in submission order.
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          description: The file id to pass in a feature's args.
                        originalName:
                          type: string
                        size:
                          type: integer
                          description: Bytes received.
              example:
                files:
                - id: f_9c21e0b4
                  originalName: portrait.jpg
                  size: 734112
        '401':
          description: Unauthorized
      operationId: postV3FilesUpload
      x-operation-id-source: derived
  /v3/files/upload-url:
    post:
      summary: Create an Upload URL
      description: 'Both routes produce the same file id; this one is for callers the multipart route shuts out. The id comes first and the bytes go second, straight to storage, over a signed URL that carries its own credential for 15 minutes. No Authorization header travels with the bytes, so an agent on MCP (whose key lives in its client config, not its shell) or a client you would rather not hand your key can finish the upload. If you can POST the file, use /v3/files/upload instead.


        The multipart route''s limits apply (30 MB, same accepted types). Both echoed headers are signed: a PUT that changes or omits either is refused by storage with a 403.


        The id means nothing until the PUT answers 200, then behaves exactly like a multipart id, 24 hour expiry included.'
      x-steps:
      - title: Ask for the URL
        body: POST the file's exact size in bytes and its media type. Nothing is uploaded yet; you are reserving an id and getting a signed address for the bytes.
        curl: "curl -X POST \"https://api.neurall.io/v3/files/upload-url\" \\\n  -H \"Authorization: nl-YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{ \"bytes\": 734112, \"contentType\": \"image/jpeg\" }'"
        response:
          file:
            id: f_51ac9d20
          uploadUrl: https://s3.amazonaws.com/neurall-uploads/f_51ac9d20?X-Amz-Signature=…
          method: PUT
          headers:
            Content-Type: image/jpeg
            Content-Length: '734112'
          expiresIn: 900
      - title: PUT the bytes to uploadUrl
        body: Send the file to `uploadUrl` with exactly the echoed headers and no Authorization header (curl derives Content-Length from the file itself). A 200 with an empty body means the id is live. The URL is good for 15 minutes; past that, start over at step 1.
        curl: "curl -X PUT \"https://s3.amazonaws.com/neurall-uploads/f_51ac9d20?X-Amz-Signature=…\" \\\n  -H \"Content-Type: image/jpeg\" \\\n  --data-binary @portrait.jpg"
      - title: Use the id like any upload
        body: 'The id now behaves exactly like one from POST /v3/files/upload: pass it in a feature''s args, and it expires 24 hours after it landed.'
        curl: "curl -X POST \"https://api.neurall.io/v3/generations\" \\\n  -H \"Authorization: nl-YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"feature\": \"image/self-portrait\",\n    \"args\": {\n      \"image\": \"f_51ac9d20\",\n      \"prompt\": \"Cinematic studio portrait, moody side light.\"\n    }\n  }'"
        response:
          generation:
            id: 9f2c1d84-6a3b-4f21-9c77-2f0a1b8e5d43
            feature: image/self-portrait
            kind: image
            status: pending
      security:
      - ApiKeyAuth: []
      tags:
      - Files
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                bytes:
                  type: integer
                  description: The file's exact size in bytes. Signed into the URL, so the upload must send precisely this many. Over 30 MB answers 413.
                contentType:
                  type: string
                  description: 'The file''s media type, e.g. `image/jpeg`. Also signed, and stored on the object: promoting an upload into a saved subject or product copies it onto the permanent asset. Must be an accepted type (image, audio, video, or PDF/ZIP/text/JSON documents) or the request answers 415.'
              required:
              - bytes
              - contentType
      responses:
        '200':
          description: The file id and where to PUT the bytes
          content:
            application/json:
              schema:
                type: object
                properties:
                  file:
                    type: object
                    properties:
                      id:
                        type: string
                  uploadUrl:
                    type: string
                  method:
                    type: string
                  headers:
                    type: object
                    description: The exact headers the PUT must carry.
                  expiresIn:
                    type: integer
                    description: Seconds the URL stays valid.
              example:
                file:
                  id: f_51ac9d20
                uploadUrl: https://s3.amazonaws.com/neurall-uploads/f_51ac9d20?X-Amz-Signature=…
                method: PUT
                headers:
                  Content-Type: image/jpeg
                  Content-Length: '734112'
                expiresIn: 900
        '400':
          description: Missing or malformed bytes or contentType
        '401':
          description: Unauthorized
        '413':
          description: The file is over 30 MB
      operationId: postV3FilesUploadUrl
      x-operation-id-source: derived
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization