Developers and agents
Duskly has one public API endpoint and a set of machine-readable descriptions of the site. There is no key, no account and no sandbox to register for.
Machine-readable index
/llms.txt— what this site is, when to use it,
when not to, and what it does not claim.
/openapi.json— OpenAPI 3.1 description./.well-known/api-catalog— RFC
9727 linkset pointing at the description above.
/sitemap.xml— every page, with hreflang
alternates for English, French, Spanish and Dutch.
MCP server
https://duskly.ai/mcp speaks the Model Context Protocol over Streamable HTTP, stateless JSON. No key, no account, no session.
{"mcpServers": {"duskly": {"type": "http", "url": "https://duskly.ai/mcp"}}}Setup instructions for Claude, Claude Code, Codex and ChatGPT are on the MCP server page.
Free, no listing needed:
duskly_classify_edit— is this edit disclosable, ambiguous, or prohibited outrightduskly_generate_disclosure— the MLS wording for every publishing surfaceduskly_list_prohibited_alterations— what no disclosure can cureduskly_list_edits— the available edits and their compliance statusduskly_verify_image— check an image for provenance marksduskly_get_pricing— what it costs and what a purchase includesduskly_start_listing— a link for a person to upload photos
For a listing, passing its id from the listing URL:
duskly_get_listing— photos, what has been edited, whether it is paid, budget leftduskly_get_listing_pack— paid listings only: download link, per-photo disclosure wording, originals pageduskly_get_checkout_url— a Stripe URL for a person to open and pay
Possession of the listing id is the authorisation, as it is on the website. A paid listing is fully readable through MCP; an unpaid one returns the checkout URL instead. No tool completes a purchase.
There is no render tool, deliberately. A render spends model credit and sits behind a browser check an automated client cannot pass, so the server hands back a link for a person to open rather than pretending it can do the work. Duskly does not take payment through MCP either: when the keyed tier lands, checkout returns a Stripe URL for a human to open.
GET and DELETE return 405. There is no SSE stream because the server sends no server-initiated messages, and no session to delete because it issues none.
Markdown instead of HTML
Any page on this site can be fetched as Markdown by sending Accept: text/markdown. Responses carry Content-Type: text/markdown and Vary: Accept. A 404 answers in Markdown too, with links onward rather than a rendered error page.
curl -H 'Accept: text/markdown' https://duskly.ai/Verifying an image
curl -X POST https://duskly.ai/api/v1/verify -F image=@photo.jpgReturns what provenance marks were found: an invisible Duskly watermark, IPTC digital source type, and whether a C2PA container appears present.
Read the result carefully before repeating it. It is a limited inspection report, not a certificate of authenticity or compliance. The absence of a mark is not evidence that an image is a camera capture — most AI editors write nothing at all, and Duskly's own paid downloads are deliberately unmarked. The C2PA field reports only that a container appears present; manifests are not parsed, signatures are not validated, and Duskly does not sign them.
Versioning
Integrate against /api/v1/verify. Breaking changes ship as a new path segment, never in place. /api/verify is an unversioned alias kept because links to it are already published, and is not covered by that promise.
A retiring version is announced with Deprecation and Sunset headers (RFC 8594) at least six months before removal.
Rate limits
No key means the limit is counted per IP. Callers without a browser bot-check token get a smaller hourly allowance than the website does. Every response carries RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset and RateLimit-Policy; a 429 adds Retry-After. Throttle on those rather than retrying into a refusal.
Errors
Every 4xx and 5xx is JSON with a stable machine-readable code, a human-readable error, and usually a detail saying how to resolve it.
{"error": "Image is larger than 20MB", "code": "image_too_large", "detail": "The limit is 20MB per image."}Codes: image_missing, image_too_large, image_unreadable, bot_check_failed, rate_limited, unavailable, not_found.
What there is no API for
Editing photos. The render endpoints spend model credit and require a browser bot check, so they are not callable by automated clients. Listing URLs are purchase credentials and are excluded in robots.txt; do not crawl, index or share them.
Questions: contact@duskly.ai.