Forms API

The Forms API is how you build, version, publish, and organize Droplet forms programmatically. Reach for it when you want to create forms from your own tooling, migrate templates in bulk, automate publishing pipelines, keep a form's content in sync with an external system, or lean on Droplet's AI helpers to draft forms and expressions. Everything you can do in the Droplet form builder has a matching endpoint here.

Forms API

Before you start

All endpoints live under the base URL https://api.droplet.io. Append the path shown on each endpoint, so GET /v1/forms/ids becomes GET https://api.droplet.io/v1/forms/ids.

Every request must include an Authorization header carrying a bearer token (a JWT): Authorization: Bearer <token>. The Overview article covers authentication in depth.

Path parameters are written with a leading colon, like :id in /v1/forms/:id. Treat those as placeholders you replace with a real value.

Successful responses share one envelope:

{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": { ... }
}

When something goes wrong, you get the same shape with "success": false and an error object (carrying code and message) instead of data. The sections below describe the data object each endpoint returns on success. Examples show the fields you will most commonly use; a response may include more, so ignore any you do not recognize.

Many read and write endpoints accept an optional include query parameter. Pass a comma-separated list (for example name,description) to control which fields come back in the response.

Listing and lookup

List form IDs

GET /v1/forms/ids

Returns the IDs of forms that match your filters, along with a total count. This is the lightweight way to page through your form library before fetching full records.

ParameterInTypeRequiredDescription
pagequeryintegerNoZero-based page index.
searchquerystringNoFree-text search across form names.
tagKeyquerystringNoFilter to forms carrying this managed tag key.
tagValuequerystringNoFilter to forms whose tag matches this value.
statusquerystringNoOne of enabled, disabled, notPublished, published.
showquerystringNoOne of all, archived, active, voided.
sortquerystringNoEither name (default) or lastCreated.
curl https://api.droplet.io/v1/forms/ids?status=published&sort=lastCreated \
  -H "Authorization: Bearer <token>"
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "count": 3,
    "ids": ["id1", "id2", "id3"]
  }
}

Fetch multiple forms by ID

POST /v1/forms/entities

Returns full form records for a list of IDs you provide. Pair this with the IDs you got from the listing endpoint to hydrate them in a single round trip.

ParameterInTypeRequiredDescription
idsbodyarrayYesArray of form IDs to fetch.
includequerystring or arrayNoComma-separated fields to include, for example name,description.
curl -X POST https://api.droplet.io/v1/forms/entities \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"ids": ["id1", "id2", "id3"]}'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": [
    {
      "id": "id1",
      "name": "Travel Request",
      "description": "Employee travel approval",
      "disabled": false,
      "loginRequired": true,
      "submitAsLoggedIn": true,
      "nextSequenceId": 42,
      "archived": false,
      "publishedVersion": "v3",
      "thumbnail": null,
      "tags": {},
      "created": "2026-01-12T09:00:00Z",
      "modified": "2026-06-01T14:30:00Z"
    }
    // ...
  ]
}

Count forms

GET /v1/forms/count

Returns just the number of forms matching your filters. Handy for pagination math or dashboard tiles where you do not need the records themselves.

ParameterInTypeRequiredDescription
statusquerystringNoOne of enabled, disabled, notPublished, published.
showquerystringNoOne of all, archived, active, voided.
searchquerystringNoFree-text search across form names.
tagKeyquerystringNoFilter by managed tag key.
tagValuequerystringNoFilter by managed tag value.
curl "https://api.droplet.io/v1/forms/count?status=published" \
  -H "Authorization: Bearer <token>"
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": { "count": 3 }
}

Get a form

GET /v1/forms/:id

Returns a single form's metadata by ID. This is the form record itself (name, settings, tags, publish state), not its version document.

ParameterInTypeRequiredDescription
idpathstringYesThe form ID.
includequerystring or arrayNoComma-separated fields to include.
curl https://api.droplet.io/v1/forms/id1 \
  -H "Authorization: Bearer <token>"
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "id": "id1",
    "name": "Travel Request",
    "description": "Employee travel approval",
    "disabled": false,
    "loginRequired": true,
    "submitAsLoggedIn": true,
    "nextSequenceId": 42,
    "archived": false,
    "publishedVersion": "v3",
    "allowPublish": true,
    "thumbnail": null,
    "tags": {},
    "permissions": {},
    "created": "2026-01-12T09:00:00Z",
    "modified": "2026-06-01T14:30:00Z"
  }
}

Form preview

GET /v1/forms/:id/preview

Returns the data needed to render a preview of a form, including the resolved version document and a little organization context. Use it to show a form exactly as a submitter would see it without publishing.

ParameterInTypeRequiredDescription
idpathstringYesThe form ID.
versionquerystringNoPreview a specific version instead of the latest draft.
inlinePreviewquerystringNoRequest an inline preview variant.
curl "https://api.droplet.io/v1/forms/id1/preview?version=v3" \
  -H "Authorization: Bearer <token>"
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "id": "id1",
    "name": "Travel Request",
    "loginRequired": true,
    "submitAsLoggedIn": true,
    "disabled": false,
    "version": {
      "id": 7,
      "version": "v3",
      "locked": false,
      "submissionsCount": 18,
      "layout": { /* ... */ },
      "workflow": { /* ... */ }
      // ...
    },
    "organization": { "name": "Acme Inc", "free": false }
  }
}

Get the published version

GET /v1/forms/:id/published

Returns the currently published version of a form, resolved and ready to render. This is what live submitters interact with.

ParameterInTypeRequiredDescription
idpathstringYesThe form ID.
curl https://api.droplet.io/v1/forms/id1/published \
  -H "Authorization: Bearer <token>"
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "id": "id1",
    "name": "Travel Request",
    "loginRequired": true,
    "submitAsLoggedIn": true,
    "disabled": false,
    "version": {
      "version": "v3",
      "publishedAt": "2026-06-01T14:30:00Z",
      "locked": true,
      "layout": { /* ... */ }
      // ...
    },
    "organization": { "name": "Acme Inc", "free": false }
  }
}

Get the next sequence ID

POST /v1/forms/:id/sequence

Returns the next submission sequence number for a form and advances the counter. Use it when you generate submission references outside of Droplet and need them to stay in step.

ParameterInTypeRequiredDescription
idpathstringYesThe form ID.
curl -X POST https://api.droplet.io/v1/forms/id1/sequence \
  -H "Authorization: Bearer <token>"
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": { "sequenceId": 43 }
}

Creating and editing

Create a form

POST /v1/forms

Creates a new, empty form with the metadata you supply. You will typically follow this with a call to create a version and add layout content.

ParameterInTypeRequiredDescription
namebodystringYesDisplay name of the form.
descriptionbodystringYesShort description.
loginRequiredbodybooleanYesWhether submitters must be signed in.
submitAsLoggedInbodybooleanYesWhether submissions are attributed to the signed-in user.
nextSequenceIdbodyintegerYesStarting submission sequence number (minimum 1).
includequerystring or arrayNoComma-separated fields to include in the response.
curl -X POST https://api.droplet.io/v1/forms \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Travel Request",
    "description": "Employee travel approval",
    "loginRequired": true,
    "submitAsLoggedIn": true,
    "nextSequenceId": 1
  }'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "id": "id1",
    "name": "Travel Request",
    "description": "Employee travel approval",
    "loginRequired": true,
    "submitAsLoggedIn": true,
    "nextSequenceId": 1,
    "disabled": false,
    "archived": false,
    "publishedVersion": null
  }
}

Create a form from a template

POST /v1/forms/create-from-template

Creates a new form by cloning a template. The new form starts with the template's layout, workflow, and settings already in place.

ParameterInTypeRequiredDescription
templateIdbodystringYesID of the template to clone.
includequerystring or arrayNoComma-separated fields to include.
curl -X POST https://api.droplet.io/v1/forms/create-from-template \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"templateId": "tmpl_travel"}'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "id": "id9",
    "name": "Travel Request",
    "disabled": false,
    "archived": false,
    "publishedVersion": null
  }
}

Duplicate a form

POST /v1/forms/:id/duplicate

Creates a copy of an existing form under a new name, carrying its content forward. Great for spinning up a variant without touching the original.

ParameterInTypeRequiredDescription
idpathstringYesID of the form to duplicate.
namebodystringYesName for the new copy.
includequerystring or arrayNoComma-separated fields to include.
curl -X POST https://api.droplet.io/v1/forms/id1/duplicate \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"name": "Travel Request (Copy)"}'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "id": "id10",
    "name": "Travel Request (Copy)",
    "disabled": false,
    "archived": false,
    "publishedVersion": null
  }
}

Update form metadata

PUT /v1/forms/:id

Updates a form's settings such as its name, description, login requirements, or whether it is disabled. Only the fields you send are changed.

ParameterInTypeRequiredDescription
idpathstringYesThe form ID.
namebodystringNoNew display name.
descriptionbodystringNoNew description.
loginRequiredbodybooleanNoWhether submitters must be signed in.
submitAsLoggedInbodybooleanNoWhether submissions are attributed to the signed-in user.
nextSequenceIdbodyintegerNoReset the sequence counter (minimum 1).
disabledbodybooleanNoEnable or disable the form.
includequerystring or arrayNoComma-separated fields to include.
curl -X PUT https://api.droplet.io/v1/forms/id1 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"description": "Updated travel approval flow"}'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "id": "id1",
    "name": "Travel Request",
    "description": "Updated travel approval flow",
    "disabled": false
    // ...
  }
}

Versions

A form's content (its layout, workflow, steps, datasets, notifications, and more) lives in versioned documents. You draft against a version, then publish it. The fields below are JSON strings on write, and resolved objects on read.

List versions

GET /v1/forms/:id/versions

Returns every version of a form, newest content first, with metadata like who last modified each one and how many submissions it has.

ParameterInTypeRequiredDescription
idpathstringYesThe form ID.
curl https://api.droplet.io/v1/forms/id1/versions \
  -H "Authorization: Bearer <token>"
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "count": 3,
    "versions": [
      {
        "id": 7,
        "version": "v3",
        "locked": false,
        "archived": false,
        "publishedAt": "2026-06-01T14:30:00Z",
        "submissionsCount": 18,
        "modifiedBy": { "name": "Ada Lovelace", "email": "ada@acme.com" }
        // ...
      }
    ]
  }
}

modifiedBy identifies whoever last changed the version and can take several shapes: a user with name and email, a service client, an account reference, or "unknown" when it cannot be resolved. Handle it defensively rather than assuming email is always present.

Create a version

POST /v1/forms/:id/versions

Creates a new draft version for a form. Send the content as JSON strings; omitted fields fall back to sensible starter defaults.

ParameterInTypeRequiredDescription
idpathstringYesThe form ID.
layoutbodystringNoJSX-style layout markup for the form.
workflowbodystringNoJSON workflow definition (steps and transitions).
stepsbodystringNoJSON step permissions.
attributesbodystringNoJSON attribute map.
datasetsbodystringNoJSON local and global datasets.
notificationsbodystringNoJSON notification rules.
integrationsbodystringNoJSON integration config.
translationsbodystringNoJSON translations.
tagExpressionsbodystringNoJSON tag expressions.
includequerystring or arrayNoComma-separated fields to include, for example version,locked.
curl -X POST https://api.droplet.io/v1/forms/id1/versions \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "layout": "<Form><Section><Input id=\"name\" label=\"Name\" /></Section><Actions /></Form>"
  }'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "id": 8,
    "version": "v4",
    "locked": false,
    "archived": false,
    "submissionsCount": 0
    // ...
  }
}

Get a version

GET /v1/forms/:id/versions/:version

Returns a single version of a form, with its content resolved into objects. Optionally pull resolved datasets along with it.

ParameterInTypeRequiredDescription
idpathstringYesThe form ID.
versionpathstringYesThe version identifier.
includequerystring or arrayNoComma-separated fields to include.
withDatasetsquerystringNoInclude resolved datasets in the response.
curl "https://api.droplet.io/v1/forms/id1/versions/v3?withDatasets=true" \
  -H "Authorization: Bearer <token>"
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "id": 7,
    "version": "v3",
    "locked": true,
    "submissionsCount": 18,
    "layout": { /* ... */ },
    "workflow": { /* ... */ },
    "datasets": { "local": {}, "global": {}, "resolved": {} }
    // ...
  }
}

Update a version

PUT /v1/forms/:id/versions/:version

Updates the content of a draft version. Send any of the content fields as JSON strings; only what you send is changed.

ParameterInTypeRequiredDescription
idpathstringYesThe form ID.
versionpathstringYesThe version identifier.
layoutbodystringNoJSX-style layout markup.
workflowbodystringNoJSON workflow definition.
stepsbodystringNoJSON step permissions.
attributesbodystringNoJSON attribute map.
datasetsbodystringNoJSON datasets.
notificationsbodystringNoJSON notification rules.
integrationsbodystringNoJSON integration config.
translationsbodystringNoJSON translations.
tagExpressionsbodystringNoJSON tag expressions.
includequerystring or arrayNoComma-separated fields to include.

Published versions are locked. Edit an unpublished draft version, then publish it to roll changes live.

curl -X PUT https://api.droplet.io/v1/forms/id1/versions/v4 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"notifications": "{\"onSubmit\":{}}"}'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "id": 8,
    "version": "v4",
    "locked": false
    // ...
  }
}

Delete a version

DELETE /v1/forms/:id/:version

Permanently deletes a single form version. This is irreversible, so reach for archiving the form instead when you only want to hide it.

ParameterInTypeRequiredDescription
idpathstringYesThe form ID.
versionpathstringYesThe version to delete.
curl -X DELETE https://api.droplet.io/v1/forms/id1/v4 \
  -H "Authorization: Bearer <token>"
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": null
}

Publishing and enabling

Publish a version

POST /v1/forms/:id/versions/:version/publish

Publishes a specific version, making it the live version that submitters see. The published version becomes locked.

ParameterInTypeRequiredDescription
idpathstringYesThe form ID.
versionpathstringYesThe version to publish.
includequerystring or arrayNoComma-separated fields to include.
curl -X POST https://api.droplet.io/v1/forms/id1/versions/v4/publish \
  -H "Authorization: Bearer <token>"
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "id": 8,
    "version": "v4",
    "locked": true,
    "publishedAt": "2026-06-21T10:00:00Z"
    // ...
  }
}

To enable or disable the public form without changing its content, send disabled to the update-metadata endpoint (PUT /v1/forms/:id).

Archive and restore

Archive forms

POST /v1/forms/archive

Archives one or more forms in a single call, moving them out of your active list. Returns how many were affected.

ParameterInTypeRequiredDescription
idsbodyarrayYesForm IDs to archive.
curl -X POST https://api.droplet.io/v1/forms/archive \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"ids": ["id1", "id2", "id3"]}'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": { "count": 3 }
}

Restore forms

POST /v1/forms/restore

Restores previously archived forms back to your active list. Returns the number restored.

ParameterInTypeRequiredDescription
idsbodyarrayYesForm IDs to restore.
curl -X POST https://api.droplet.io/v1/forms/restore \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"ids": ["id1", "id2", "id3"]}'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": { "count": 3 }
}

Tags

Managed tags are key and value pairs you attach to forms to organize and filter them. These endpoints add or remove a tag across many forms at once.

Add a tag to forms

PUT /v1/forms/tags/:key/add

Sets a managed tag value on the listed forms for the given tag key.

ParameterInTypeRequiredDescription
keypathstringYesThe managed tag key.
idsbodyarrayYesForm IDs to tag.
valuebodyanyYesThe value to assign for this tag key.
curl -X PUT https://api.droplet.io/v1/forms/tags/department/add \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"ids": ["id1", "id2"], "value": "Finance"}'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": { "count": 2 }
}

Remove a tag from forms

PUT /v1/forms/tags/:key/remove

Removes the managed tag with the given key from the listed forms.

ParameterInTypeRequiredDescription
keypathstringYesThe managed tag key.
idsbodyarrayYesForm IDs to untag.
curl -X PUT https://api.droplet.io/v1/forms/tags/department/remove \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"ids": ["id1", "id2"]}'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": { "count": 2 }
}

Translation

Translate content

POST /v1/forms/translate

Translates a string or list of strings into a target language. Use it to localize labels and copy before saving them into a version's translations.

ParameterInTypeRequiredDescription
contentbodystring or array of stringsYesThe text (or texts) to translate.
tobodystringYesTarget language code, for example es, fr, de, or zh-TW. A wide set of language codes is supported.
frombodystringNoSource language code. If omitted, the source language is detected automatically.
curl -X POST https://api.droplet.io/v1/forms/translate \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"content": ["Submit", "Cancel"], "to": "es"}'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "Submit": "Enviar",
    "Cancel": "Cancelar"
  }
}

AI helpers

These endpoints let Droplet's AI draft forms, write expressions, and pull content from a source page. They are the same helpers powering the AI features in the form builder.

Generate an expression

POST /v1/forms/ai/generate-expression

Generates a form expression (for display rules, formulas, validation, workflow conditions, and more) from a plain-language prompt and the surrounding form context. Any problems it finds come back in an errors array.

ParameterInTypeRequiredDescription
formIdbodystringYesThe form the expression belongs to.
versionbodystringYesThe version being edited.
promptbodystringYesPlain-language description of the expression you want.
elementInfobodyobjectYesMetadata about the form's elements.
workflowStepsbodyarray of stringsYesThe workflow step names in scope.
datasetsbodyobjectYesObject with local and global datasets.
optionsbodyobjectYesRequires expressionType and currentExpression; elementId is optional. expressionType is one of layoutPropDisplay, layoutPropFormula, layoutPropMin, layoutPropMax, layoutPropDisplayRows, layoutPropValidate, layoutPropOptions, workflowEntry, workflowIf, workflowAssign, notificationIf, or notificationRecipients.
curl -X POST https://api.droplet.io/v1/forms/ai/generate-expression \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "formId": "id1",
    "version": "v4",
    "prompt": "Show this field only when amount is over 1000",
    "elementInfo": {},
    "workflowSteps": ["start", "completed"],
    "datasets": { "local": {}, "global": {} },
    "options": {
      "expressionType": "layoutPropDisplay",
      "currentExpression": ""
    }
  }'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "expression": "amount > 1000",
    "errors": [],
    "promptId": "prompt_77"
  }
}

Generate a form

POST /v1/forms/ai/generate-form

Generates a complete new form from a source URL, returning the created form record. Point it at a page that describes or shows a form and let AI build the starting point.

ParameterInTypeRequiredDescription
urlbodystringYesSource URL to generate the form from.
curl -X POST https://api.droplet.io/v1/forms/ai/generate-form \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/intake-form"}'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "id": "id11",
    "name": "Intake Form",
    "disabled": false,
    "archived": false,
    "publishedVersion": null
  }
}

Extract form content

POST /v1/forms/ai/extract-form-content

Extracts structured form content (a title, description, and sections) from a source URL without creating a form. Set isAppending to true to add to existing content rather than replace it.

ParameterInTypeRequiredDescription
urlbodystringYesSource URL to extract content from.
isAppendingbodybooleanNoWhether to append to existing content.
curl -X POST https://api.droplet.io/v1/forms/ai/extract-form-content \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/intake-form"}'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "title": "Intake Form",
    "description": "Collects new client details",
    "sections": [
      {
        "type": "Section",
        "props": { "id": "section1", "children": [ /* ... */ ] }
      }
    ]
  }
}

Update an AI prompt result

PUT /v1/forms/ai/prompt-result/:id

Records whether a saved AI prompt result was accepted or rejected. This feedback helps tune future suggestions.

ParameterInTypeRequiredDescription
idpathstringYesThe prompt result ID (the promptId returned by generate-expression).
acceptedbodybooleanYesWhether the suggestion was accepted.
curl -X PUT https://api.droplet.io/v1/forms/ai/prompt-result/prompt_77 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"accepted": true}'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "id": "prompt_77",
    "accepted": true,
    "expressionType": "layoutPropDisplay",
    "prompt": "Show this field only when amount is over 1000",
    "expression": "amount > 1000"
  }
}

Thumbnails and uploads

Generate thumbnails

POST /v1/forms/generate-thumbnails

Queues thumbnail generation for specific forms or entire organizations. Pass backfill to (re)generate missing thumbnails in bulk.

ParameterInTypeRequiredDescription
backfillbodybooleanNoGenerate missing thumbnails in bulk.
formIdsbodyarrayNoSpecific form IDs to generate thumbnails for.
organizationIdsbodyarrayNoOrganizations whose forms should get thumbnails.
curl -X POST https://api.droplet.io/v1/forms/generate-thumbnails \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"formIds": ["id1", "id2", "id3"]}'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": { "count": 3 }
}

Upload screenshot files

POST /v1/forms/screenshot-file

Uploads image files used by the AI-assisted form workflows (for example, screenshots you want the AI to read). Returns a URL and per-page URLs for the uploaded content.

ParameterInTypeRequiredDescription
filesbodyarrayYesFiles to upload. Each item has file (the encoded file) and fileType.
files[].filebodystringYesThe file contents.
files[].fileTypebodyobjectYesObject with mime and ext (for example image/png and png).
curl -X POST https://api.droplet.io/v1/forms/screenshot-file \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "files": [
      {
        "file": "<base64-encoded-image>",
        "fileType": { "mime": "image/png", "ext": "png" }
      }
    ]
  }'
{
  "requestId": "req_a1b2c3",
  "success": true,
  "data": {
    "url": "https://files.droplet.io/uploads/screenshot1.png",
    "pageUrls": ["https://files.droplet.io/uploads/screenshot1-p1.png"]
  }
}
Last reviewed by Nick Duell and published on June 22, 2026 3PM ET