Upload an Asset
Uploads a new file into the project asset library.
The HTTP path is POST /api/files. The body must be multipart/form-data with a single field file.
To set alt text, title, and other descriptive fields after upload, use Bulk Asset Operations (PATCH /api/files/bulk/metadata). The upload endpoint validates and stores the binary only; optional metadata fields some clients send alongside the file are not applied by this route.
Request
POST /api/files HTTP/1.1
Host: app.nomacms.com
project-id: <project-uuid>
Authorization: Bearer <api-token>
Accept: application/json
Content-Type: multipart/form-data; boundary=...Requires the create ability on the token.
Form fields
| Field | Required | Description |
|---|---|---|
file | Yes | The file to upload. |
Limits (server defaults)
| Rule | Value |
|---|---|
| Allowed extensions | Common image, video, audio, office, and text types (for example jpg, png, webp, pdf, mp4, mp3; full list is defined in the product configuration). |
If validation fails, the API responds with 422 and a message / errors payload.
Response (201)
JSON object with the same fields as Get an Asset (one new asset).
Errors
| Status | When |
|---|---|
| 400 | Missing project-id or project cannot be resolved (see Authentication) |
| 401 | Missing or invalid bearer token |
| 403 | Token does not have create (or *) |
| 404 | No project with that UUID |
| 413 | Request body too large (for example reverse proxy or PHP limits below application validation) |
| 422 | Validation failed (missing file, wrong MIME type, or size over limit) |
| 429 | Rate limited |
Example
import { createClient } from "@nomacms/js-sdk"
const client = createClient({
projectId: process.env.NOMA_PROJECT_ID!,
apiKey: process.env.NOMA_API_KEY!,
})
// Pass a browser `File` or Node `Buffer` — see /js-sdk/assets/
const created = await client.assets.upload(fileOrBuffer)
console.log(created)import axios from "axios"
import FormData from "form-data"
import fs from "node:fs"
async function main() {
const form = new FormData()
form.append("file", fs.createReadStream("./photo.jpg"))
const { data } = await axios.post("https://app.nomacms.com/api/files", form, {
headers: {
...form.getHeaders(),
"project-id": process.env.NOMA_PROJECT_ID!,
Authorization: `Bearer ${process.env.NOMA_API_KEY}`,
Accept: "application/json",
},
maxBodyLength: Infinity,
maxContentLength: Infinity,
})
console.log(data)
}
void main()<?php
$ch = curl_init('https://app.nomacms.com/api/files');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'project-id: ' . getenv('NOMA_PROJECT_ID'),
'Authorization: Bearer ' . getenv('NOMA_API_KEY'),
'Accept: application/json',
],
CURLOPT_POSTFIELDS => [
'file' => new CURLFile(__DIR__ . '/photo.jpg'),
],
CURLOPT_RETURNTRANSFER => true,
]);
echo curl_exec($ch);curl -sS -X POST \
-H "project-id: $NOMA_PROJECT_ID" \
-H "Authorization: Bearer $NOMA_API_KEY" \
-H "Accept: application/json" \
-F "file=@./photo.jpg" \
"https://app.nomacms.com/api/files"package main
import (
"bytes"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
var body bytes.Buffer
writer := multipart.NewWriter(&body)
part, _ := writer.CreateFormFile("file", "photo.jpg")
f, _ := os.Open("photo.jpg")
_, _ = io.Copy(part, f)
_ = f.Close()
_ = writer.Close()
req, err := http.NewRequest("POST", "https://app.nomacms.com/api/files", &body)
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("project-id", os.Getenv("NOMA_PROJECT_ID"))
req.Header.Set("Authorization", "Bearer "+os.Getenv("NOMA_API_KEY"))
req.Header.Set("Accept", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
_, _ = io.Copy(os.Stdout, res.Body)
}require "net/http"
require "uri"
uri = URI("https://app.nomacms.com/api/files")
req = Net::HTTP::Post.new(uri)
req["project-id"] = ENV.fetch("NOMA_PROJECT_ID")
req["Authorization"] = "Bearer #{ENV.fetch('NOMA_API_KEY')}"
req["Accept"] = "application/json"
form_data = [["file", File.open("photo.jpg")]]
req.set_form form_data, "multipart/form-data"
Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
puts http.request(req).body
endimport os
from pathlib import Path
import urllib.request
boundary = "----PythonFormBoundary7MA4YWxkTrZu0gW"
file_path = Path("photo.jpg")
body = (
f"--{boundary}\r\n"
f'Content-Disposition: form-data; name="file"; filename="{file_path.name}"\r\n'
f"Content-Type: application/octet-stream\r\n\r\n".encode()
+ file_path.read_bytes()
+ f"\r\n--{boundary}--\r\n".encode()
)
req = urllib.request.Request(
"https://app.nomacms.com/api/files",
data=body,
method="POST",
headers={
"project-id": os.environ["NOMA_PROJECT_ID"],
"Authorization": f"Bearer {os.environ['NOMA_API_KEY']}",
"Accept": "application/json",
"Content-Type": f"multipart/form-data; boundary={boundary}",
},
)
with urllib.request.urlopen(req) as res:
print(res.read().decode())Related
- Bulk Asset Operations - Multi-file upload and metadata updates
- Get an Asset - Response shape
- Authentication - Headers and abilities
- JavaScript SDK -
assets.upload