Home
Form Submissions

form_submission_exported

Sent when a form submission export (a ZIP file) requested through the API finishes, whether it succeeded or failed.

Exports are generated asynchronously, so subscribe to this event instead of polling the export request.

relationships.object.data identifies the export request, and included contains it. Check its status: success means url links to the file, failure means the export failed and url is null.

The url is a signed link that expires 15 minutes after the event was created, and a retried delivery carries the same link. If it has expired, retrieve the export request from the API to get a fresh one.

The payload below is the default JSON:API document. The webhook's payload_include, payload_fields and payload_transformation_template change it, and its filter decides whether the event is sent at all.

Request

We send the event to your webhook's url with POST (or the webhook's http_method) and a JSON:API document as the body (Content-Type: application/vnd.api+json). See Receiving Webhooks for retries and Webhook Event Signatures to verify the request.

Headers

HeaderDescription
X-TINT-Signaturetimestamp,signature, where timestamp is the Unix time (in seconds) at which the delivery was signed and signature is the Base64-encoded HMAC-SHA256 of timestamp.body, keyed with the webhook's signing secret. Only sent when the webhook has a signing secret. Every attempt is signed again, so retries carry a new timestamp. See Webhook Event Signatures.
API-VersionThe API version the payload was serialized with, unless the webhook overrides this header.
User-AgentAlways TINT Webhook/2.0, unless the webhook overrides this header.

Payload

FieldTypeDescription
dataobject
data.idstringThe event ID. It stays the same on every retry of this event, so use it to detect duplicate deliveries. It is also the ID to use with Retrieve a webhook event.
data.typestringAlways event. One of event.
data.attributesobject
data.attributes.namestringThe event name. One of form_submission_exported.
data.attributes.created_atstring (date-time)When the event happened (the event was recorded), not when this delivery was sent. Retries keep the original value.
data.relationshipsobject
data.relationships.objectobjectThe export request this event is about.
data.relationships.object.dataobject
data.relationships.object.data.typestringOne of form_submission_export_request.
data.relationships.object.data.idstring
data.relationships.teamobjectThe team the webhook belongs to.
data.relationships.team.dataobject
data.relationships.team.data.typestringOne of team.
data.relationships.team.data.idstring

Included resources

The sideloaded resources: the export request.

form_submission_export_request

FieldTypeDescription
idstringThe ID of the export request.
typestringOne of form_submission_export_request.
attributesobject
attributes.status (optional)stringpending while the export is being generated, then success or failure. One of pending, success, failure.
attributes.url (optional)string or null (uri)Once status is success, a signed URL to a ZIP file containing form_submissions.csv (and the submitted files when include_files was true), valid for 15 minutes. Every request returns a new URL. null until then.
relationships (optional)objectA relationship's data is only present when it's listed in the include query parameter; otherwise its meta.included is false.
relationships.experience (optional)objectThe experience whose submissions are exported.
relationships.experience.data (optional)object
relationships.experience.meta (optional)object
relationships.form (optional)objectThe same resource as experience.
relationships.form.data (optional)object
relationships.form.meta (optional)object
relationships.user (optional)objectThe user who requested the export.
relationships.user.data (optional)object
relationships.user.meta (optional)object
links (optional)object
links.self (optional)string (uri)The URL of the export request.

Example

{
  "data": {
    "id": "1377465",
    "type": "event",
    "attributes": {
      "created_at": "2025-03-14T16:42:07.000Z",
      "name": "form_submission_exported"
    },
    "relationships": {
      "object": {
        "data": {
          "type": "form_submission_export_request",
          "id": "OxZZQtuh5sXIKA"
        }
      },
      "team": {
        "data": {
          "type": "team",
          "id": "1"
        }
      }
    }
  },
  "included": [
    {
      "id": "OxZZQtuh5sXIKA",
      "type": "form_submission_export_request",
      "attributes": {
        "status": "success",
        "url": "https://exports.example.com/OxZZQtuh5sXIKA.zip?X-Amz-Expires=900&X-Amz-Signature=5d41402abc4b2a76"
      },
      "relationships": {
        "experience": {
          "meta": {
            "included": false
          }
        },
        "form": {
          "meta": {
            "included": false
          }
        },
        "user": {
          "meta": {
            "included": false
          }
        }
      },
      "links": {
        "self": "https://api.tintup.com/v2/teams/1/experiences/2012/form_submissions/export/requests/OxZZQtuh5sXIKA"
      }
    }
  ]
}

Responses

StatusDescription
404404 Not Found or 410 Gone stops delivery of this event immediately: it is marked failure and not retried. The attempt still counts toward the webhook's failure limit.
410404 Not Found or 410 Gone stops delivery of this event immediately: it is marked failure and not retried. The attempt still counts toward the webhook's failure limit.
2XXAny status below 400 (typically 2XX) acknowledges the event: we mark it success and don't send it again. The response body is ignored (we store it with the attempt, for your reference). Redirects are not followed, and a 3XX response also counts as acknowledged, so point the webhook at the final URL.
OtherAny other 4XX or 5XX status, a timeout or a connection error fails the attempt, and we retry up to 7 more times with an increasing delay (roughly 1 minute, 1 minute, 2 minutes, 13 minutes, 1 hour, 4 hours, then 13 hours later), after which the event is marked failure. More than 50 failed attempts for the same webhook within a week, without a successful delivery in between, set the webhook to inactive.