Skip to content
nexdoc.design Docs

Files and assets

Presigned uploads versus one-shot multipart — how to attach logos, images, PDFs, and text files to a run.

Runs can include images and PDFs. There are two ways to attach them.

Allowed uploads

KindExtensionscontent_type
Image.pngimage/png
Image.jpg / .jpegimage/jpeg
Image.gifimage/gif
Image.webpimage/webp
Image.heic / .heifimage/heic / image/heif
Image.svgimage/svg+xml
Document.pdfapplication/pdf
Text.md / .txt / .csv / .jsontext/markdown, text/plain, text/csv, application/json

Office formats (.docx, .pptx, and so on) return 400. The worker normalizes uploads (exotic images → PNG, PDF → page PNGs + text, CSV/JSON/MD/TXT → content.md). Brand colors and fonts may also go in instructions.

POST /v1/jobs/:job_id/runs as multipart/form-data:

FieldTypeDescription
formattextFormat slug
instructionstextDesign brief
contenttext or fileSource copy (content.md)
filesfile (repeatable)images, PDF, or text files, stored immediately
file_idstextOptional JSON array of existing file_… ids
assetstextOptional JSON [{name, file_id}]
notify_emailtexttrue to email the account owner when the run finishes
webhook_urltextOptional; delivery is not guaranteed — prefer notify_email or poll
code
curl -sS -X POST "$NXD_API_URL/v1/jobs/$JOB/runs" \
  -H "Authorization: Bearer $NXD_API_KEY" \
  -F "format=business-card" \
  -F "instructions=Use the logo; minimal typography" \
  -F "content=# Jane Doe\nFounder, Acme" \
  -F "files=@./logo.png;type=image/png;filename=logo.png"

Markdown image references whose basename matches an uploaded file are rewritten to assets/<filename>.

Presigned upload (JSON runs / reuse)

Use when bytes live on a server, when reusing one asset across many runs, or when the multipart body would be large.

1. Request an upload URL

code
curl -sS -X POST "$NXD_API_URL/v1/files/request-upload" \
  -H "Authorization: Bearer $NXD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "logo.png",
    "content_type": "image/png",
    "size_bytes": 18432
  }' | jq
code
{
  "file_id": "file_...",
  "upload_url": "https://...",
  "uri": "s3://...",
  "expires_at": "..."
}

2. PUT the bytes

Upload to upload_url (not the NexDoc API host):

code
curl -sS -X PUT "$UPLOAD_URL" \
  -H "Content-Type: image/png" \
  --data-binary @logo.png

3. Wait until ready

code
curl -sS "$NXD_API_URL/v1/files/$FILE_ID" \
  -H "Authorization: Bearer $NXD_API_KEY" | jq '{status, filename}'

status moves pending_upload → ready.

4. Reference in a JSON run

code
curl -sS -X POST "$NXD_API_URL/v1/jobs/$JOB/runs" \
  -H "Authorization: Bearer $NXD_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"format\": \"landing-page\",
    \"instructions\": \"Hero with logo top-left\",
    \"content\": \"# Acme\",
    \"files\": [\"$FILE_ID\"],
    \"assets\": [{\"name\": \"logo.png\", \"file_id\": \"$FILE_ID\"}]
  }"
  • files — include these file ids in the workspace.
  • assets — map a display name (path under assets/) to a file_id.

Delete a file

code
curl -sS -X DELETE "$NXD_API_URL/v1/files/$FILE_ID" \
  -H "Authorization: Bearer $NXD_API_KEY" | jq

Requires scope files:rw.