Files

Files let you upload local JPEG, PNG, and WebP images to Flint before attaching them to a product, variant, bundle, payment link, subscription plan, merchant logo, or merchant icon.

Call POST /v1/files with purpose, the exact content_type, and size_bytes from 1 to 5,242,880. For example:

JSON
{
  "purpose": "product",
  "content_type": "image/png",
  "size_bytes": 12345
}

The 201 response returns a file_id beginning with file_, status awaiting_upload, and an upload object. Send the image bytes to upload.url using upload.method and every value in upload.headers verbatim. The signed URL expires after 15 minutes. Keep it out of logs.

After the PUT succeeds, call POST /v1/files/{file_id}/complete with no body or {}. The 200 response returns the same file at status ready, with its canonical url, width, and height. Calling complete again returns the ready file. Completing before the bytes arrive returns 409 FILE_NOT_UPLOADED and leaves the file available for upload.

Attach a ready file by passing its url as images[].source_url on a catalog or branding resource. Canonical Flint URLs attach without refetching. The ready file's expires_at is the last instant it can be attached, 24 hours after processing. Attachment removes that deadline. There is no file read route; keep the returned file details.

Use the write scope for the purpose: commerce.products.write for product and product_variant, commerce.bundles.write for bundle, checkouts.payment_links.write for payment_link, commerce.subscription_plans.write for subscription_plan, and merchants.profile.write for merchant_logo and merchant_icon. Logos and icons are merchant-wide, including when uploaded from a sandbox. Other files belong to the environment that created them; completing one from another environment returns 404 RESOURCE_NOT_FOUND.

Partner installs can upload commerce images. They cannot upload merchant logos or icons because merchants.profile.write is not grantable to partner installs; those purposes return 403 INSUFFICIENT_SCOPE with scope_requirement.

Both routes accept an optional Idempotency-Key, scoped to merchant, credential, environment, and route, with file_id also part of the completion identity. Replays return the original result and do not extend upload or attachment deadlines. If an upload URL expires, create a new file. If a create response cannot be recovered, contact support with X-Request-Id before starting another upload.

Create a file#

POST/v1/filesIdempotent

Requires scope checkouts.payment_links.write or commerce.bundles.write or commerce.products.write or commerce.subscription_plans.write or merchants.profile.write

Upload a local image to Flint. Create a file, PUT the bytes to upload.url with upload.method and every upload.headers value, then POST /v1/files/{file_id}/complete. The URL works for 15 minutes. Purpose requires its own write scope: product and product_variant use commerce.products.write; bundle uses commerce.bundles.write; payment_link uses checkouts.payment_links.write; subscription_plan uses commerce.subscription_plans.write; merchant_logo and merchant_icon use merchants.profile.write. Logo and icon files are merchant-wide; all other purposes belong to the authenticated environment. Partner installs can upload commerce images but cannot upload merchant_logo or merchant_icon: those purposes return INSUFFICIENT_SCOPE with scope_requirement because merchants.profile.write is not grantable to installs. Idempotency is scoped to merchant, credential, environment, and route. A replay returns the original upload target without extending its expiry. If a result cannot be recovered, contact support with X-Request-Id before starting another upload.

Request body

content_typeenumRequired
  • image/jpeg
  • image/png
  • image/webp
purposeenumRequired

What the image will be used for. Partner installs support the five commerce purposes; merchant_logo and merchant_icon require merchants.profile.write, which partner installs cannot grant, and return INSUFFICIENT_SCOPE with scope_requirement.

  • product
  • product_variant
  • bundle
  • payment_link
  • subscription_plan
  • merchant_logo
  • merchant_icon
size_bytesintegerRequired

Response · 201

dataobjectRequired

An image uploaded to Flint. Create the file, PUT its bytes to upload.url with upload.headers, then complete it. Attach the ready url as images[].source_url on a catalog or branding resource. A ready unattached file expires after 24 hours; attachment removes that deadline. Each upload has its own file_id, including uploads of identical bytes.

metaobject
request_idstring
curl -X POST https://api.withflintpay.com/v1/files \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-key" \
  -d '{
    "content_type": "image/png",
    "purpose": "product",
    "size_bytes": 12345
  }'

Complete a file#

POST/v1/files/{file_id}/completeIdempotent

Requires scope checkouts.payment_links.write or commerce.bundles.write or commerce.products.write or commerce.subscription_plans.write or merchants.profile.write

After PUT succeeds, complete the file to process its image. Returns the ready file; completing a ready file again returns it. Send no request body or {}. Completing before the bytes arrive returns FILE_NOT_UPLOADED and leaves the file awaiting_upload. Attach the returned url as images[].source_url before expires_at, 24 hours after processing. Completion requires the purpose's write scope, with the same merchant-wide branding and environment boundaries as createFile. Partner installs can upload commerce images but cannot upload merchant_logo or merchant_icon: those purposes return INSUFFICIENT_SCOPE with scope_requirement because merchants.profile.write is not grantable to installs. Idempotency is scoped to merchant, credential, environment, route, and file_id. A replay returns the original result; it does not extend upload or attachment deadlines. After a lost completion response, repeat this route with the same key and file_id.

Path parameters

file_idstringRequired

Flint file ID.

Response · 200

Same response as Create a file.

curl -X POST https://api.withflintpay.com/v1/files/file_01J00000000000000000000000/complete \
  -H "Flint-Version: 2026-09-07" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a-unique-key" \
  -d '{}'

Was this helpful?