Skip to content
contact.
FeaturesHow it worksDocsContact
Log inGet started

Guides

  • Getting started
  • Embedding
  • Field types and schema
  • File uploads
  • Delivery and integrations
  • Spam protection and limits
  • API reference
  • Troubleshooting & FAQ

Operations

  • Admin & self-hosting
Open dashboard →
UPLOADS

File uploads.

File uploads are a two-step flow: upload the file to get an ID, then submit your form with that ID as the field value.

How the flow works

  1. Enable uploads for the form and add a media field to the schema.
  2. POST the file as multipart/form-data to the upload endpoint.
  3. Receive an uploadId (plus a temporary preview URL).
  4. Submit your JSON form data with the uploadId as the field value.

1. Upload the file

Send the file as a single file part. Do not set the Content-Type header yourself — the browser must add the multipart boundary.

const form = new FormData();
form.append("file", fileInput.files[0]);

const upload = await fetch("https://contact.kirandhakal.me/v1/forms/YOUR_PUBLIC_KEY/upload", {
  method: "POST",
  body: form // do not set Content-Type; the browser adds the multipart boundary
});
if (!upload.ok) {
  const error = await upload.json();
  throw new Error(error.detail);
}
const { uploadId } = await upload.json();

2. Submit the upload ID

Send the returned uploadId as the value of your media field. Contact verifies that the ID belongs to this form, then attaches the file to the submission.

await fetch("https://contact.kirandhakal.me/v1/forms/YOUR_PUBLIC_KEY/submissions", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID()
  },
  body: JSON.stringify({
    name: "Alex Morgan",
    email: "alex@example.com",
    attachment: uploadId
  })
});
Never embed file data directly. Base64 data: URLs, arbitrary URLs, and storage object keys are rejected with 422 (INVALID_UPLOAD_REFERENCE).

Limits and defaults

SettingDefaultRange
Max file size10 MB1–100 MB (server cap)
Files per request11–20
Files per field11–20
Workspace storage1 GBServer-configured

Allowed file types

Contact inspects the file’s magic bytes and extension and requires the declared MIME type to agree with them. Supported types are:

  • Images: JPEG, PNG, GIF, WebP
  • Documents: PDF, DOC, DOCX
  • Audio: MP3, WAV, OGG, M4A/AAC, FLAC
  • Video: MP4/MOV, WebM

Restrict a field further with allowedTypes, using tokens such as image/*, application/pdf, or .png. Files that fail validation return 400 (UNSUPPORTED_FILE_TYPE) or 413 (FILE_TOO_LARGE).

Storage and lifecycle

Uploaded files are stored in object storage. Uploads that are never attached to a submission expire automatically, and files are deleted according to your retention settings. See the Privacy Policy for retention details and keep your own copies of anything you need to keep.

Previous Field types and schemaNextDelivery and integrations
contact.

Your frontend. Our form backend.

How to useIntegrationsContactTermsPrivacy policy
© 2026 ContactDesigned & developed by Kiran Dhakal