Skip to content

Endpoints

Two endpoints cover the API workflow. Both accept a multipart form with a single image field (JPEG, PNG, or WebP, up to 25 MB) and answer JSON. Authentication is the bearer key.

POST /api/v1/protect

Embeds the machine-readable opt-out signal in the file metadata. Optional Dashboard layers are intentionally not guessed by the API’s default endpoint. Each successful call counts one image against your allowance; failed transforms are refunded and do not count.

Field Type Notes
image file (multipart) Required. image/* content type, up to 25 MB.
Terminal window
curl -X POST https://api.noaishield.com/api/v1/protect \
-H "Authorization: Bearer $NOAI_API_KEY" \
-o response.json
// JavaScript (Node 18+)
import { readFile, writeFile } from "node:fs/promises";
const bytes = await readFile("artwork.png");
const form = new FormData();
form.set("image", new Blob([bytes], { type: "image/png" }), "artwork.png");
const res = await fetch("https://api.noaishield.com/api/v1/protect", {
method: "POST",
headers: { authorization: `Bearer ${process.env.NOAI_API_KEY}` },
body: form,
});
if (!res.ok) throw new Error((await res.json()).error);
const data = await res.json();
await writeFile(data.filename, Buffer.from(data.imageBase64, "base64"));
# Python (requests)
import base64, os, requests
with open("artwork.png", "rb") as f:
res = requests.post(
"https://api.noaishield.com/api/v1/protect",
headers={"Authorization": f"Bearer {os.environ['NOAI_API_KEY']}"},
files={"image": ("artwork.png", f, "image/png")},
)
res.raise_for_status()
data = res.json()
with open(data["filename"], "wb") as out:
out.write(base64.b64decode(data["imageBase64"]))
{
"imageBase64": "...",
"mimeType": "image/png",
"filename": "noai-shield-marked.png",
"sha256": "...",
"signals": ["iptc.dataMining"],
"creditsRemaining": 42
}
Field Description
imageBase64 The marked image, base64-encoded. Decode it and save it as your published copy.
mimeType Media type of the produced bytes. Re-encoding can change it (for example WebP in, PNG out).
filename Suggested file name, extension matching the produced bytes.
sha256 SHA-256 of the marked bytes. This API call does not create a PDF or hosted record.
signals The machine-readable opt-out signals written, e.g. iptc.dataMining.
creditsRemaining Image credits left after this successful marking call.

The produced format can differ from the upload. Always name and serve the file from the response fields, never from the input’s extension.

POST /api/v1/verify

Checks the opt-out signal, NoAI Shield service-signature metadata, and the experimental pixel fingerprint. Free, and uses the same verification core as the dashboard.

Field Type Notes
image file (multipart) Required. image/* content type, up to 25 MB.
Terminal window
curl -X POST https://api.noaishield.com/api/v1/verify \
-H "Authorization: Bearer $NOAI_API_KEY" \
// JavaScript (Node 18+)
import { readFile } from "node:fs/promises";
const bytes = await readFile("artwork.png");
const form = new FormData();
form.set("image", new Blob([bytes], { type: "image/png" }), "artwork.png");
const res = await fetch("https://api.noaishield.com/api/v1/verify", {
method: "POST",
headers: { authorization: `Bearer ${process.env.NOAI_API_KEY}` },
body: form,
});
const { optedOut } = await res.json();
# Python (requests)
import os, requests
with open("artwork.png", "rb") as f:
res = requests.post(
"https://api.noaishield.com/api/v1/verify",
headers={"Authorization": f"Bearer {os.environ['NOAI_API_KEY']}"},
files={"image": ("artwork.png", f, "image/png")},
)
print(res.json()["optedOut"])
{
"optedOut": true,
"signals": ["iptc.dataMining"],
"provenance": {
"present": false,
"valid": false,
"verifiable": true
},
"fingerprint": {
"present": false,
"confidence": 0.51,
"blocks": 4096
},
"sha256": "..."
}
Field Description
optedOut true when the image carries the standardized IPTC/PLUS opt-out field.
signals The signals found, empty when the field is absent.
provenance Whether a NoAI Shield service-signature tag is present, whether this server can verify it, and whether it is valid.
fingerprint Statistical result from our experimental in-pixel detector. confidence is a match ratio, not a guarantee of authorship.
sha256 SHA-256 of the uploaded bytes, for matching against a dated NoAI Shield record.

Checking is free, so pipelines can check first and add the field only when it is absent:

const verdict = await callApi("/api/v1/verify", bytes);
if (!verdict.optedOut) {
const done = await callApi("/api/v1/protect", bytes);
await save(done);
}

This pattern is useful for pipelines that want to avoid marking an already-marked file. The repository pull-request flow checks first; individual clients may choose to mark directly.

Strictly necessary storage remembers your choice. See the privacy policy for details.