Skip to main content
GET
/
responses
/
{id}
curl -X GET 'https://connect.penbox.io/v1/responses/660e8400-e29b-41d4-a716-446655440000' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Accept: application/json'
{
  "data": {
    "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
    "type": "responses",
    "attributes": {
      "$created_at": "2023-11-07T05:31:56Z",
      "$updated_at": "2023-11-07T05:31:56Z",
      "completed_at": "2023-11-07T05:31:56Z",
      "declined_at": "2023-11-07T05:31:56Z",
      "user": {
        "email": "<string>",
        "given_name": "<string>",
        "family_name": "<string>",
        "phone": "<string>",
        "locale": "<string>"
      },
      "data": {},
      "rating": "<string>"
    },
    "relationships": {
      "request": {
        "data": {
          "id": "<string>",
          "type": "requests"
        }
      },
      "attachments": {
        "data": [
          {
            "id": "<string>",
            "type": "attachments"
          }
        ]
      }
    }
  },
  "included": [
    {
      "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
      "created_at": "2023-11-07T05:31:56Z",
      "status": "draft",
      "archived": true,
      "archived_at": "2023-11-07T05:31:56Z",
      "processed_at": "2023-11-07T05:31:56Z",
      "active_from": "2023-11-07T05:31:56Z",
      "active_until": "2023-11-07T05:31:56Z",
      "links": {
        "fill": "<string>",
        "app": "<string>"
      },
      "user": {
        "anonymous": true,
        "email": "<string>",
        "phone": "<string>",
        "given_name": "<string>",
        "family_name": "<string>"
      },
      "owner": {
        "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
        "email": "<string>"
      },
      "flow": {
        "slug": "<string>"
      },
      "data": {},
      "external_args": {},
      "options": {},
      "responses": [
        {
          "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
          "completed_at": "2023-11-07T05:31:56Z",
          "declined_at": "2023-11-07T05:31:56Z",
          "data": {},
          "user": {
            "anonymous": true,
            "ip": "<string>",
            "email": "<string>",
            "phone": "<string>",
            "locale": "<string>",
            "given_name": "<string>",
            "family_name": "<string>",
            "user-agent": "<string>",
            "accept-language": "<string>"
          },
          "attachments": [
            {
              "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
              "name": "<string>",
              "type": "<string>",
              "metadata": {
                "size": 123,
                "width": 123,
                "height": 123
              },
              "uri": "<string>"
            }
          ],
          "signatures": {},
          "files": {}
        }
      ],
      "notifications": [
        {
          "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
          "status": "pending",
          "method": "sms",
          "at": "2023-11-07T05:31:56Z",
          "to": "<string>",
          "from": "<string>",
          "cc": "<string>",
          "bcc": "<string>",
          "system": true,
          "locale": "<string>",
          "template": "<string>",
          "variables": {},
          "active": true,
          "error": "<string>",
          "message_id": "<string>",
          "attachments": {},
          "deleted_at": "2023-11-07T05:31:56Z"
        }
      ]
    }
  ]
}
Retrieve complete form response data including answers and attachments.
Form responses are called responses in the API. Each form (request) can have one or more responses as contacts fill them out.
curl -X GET 'https://connect.penbox.io/v1/responses/660e8400-e29b-41d4-a716-446655440000' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Accept: application/json'

Response Formats

The endpoint supports two response formats controlled by the Accept header:
FormatAccept HeaderDescription
JSONapplication/jsonStructured data including all form fields and file references
PDFapplication/pdfGenerated PDF of the complete form response

Response Fields

Response Attributes

FieldTypeDescription
$created_atstringISO 8601 timestamp when response was created
$updated_atstringISO 8601 timestamp of last update
completed_atstring/nullISO 8601 timestamp when completed (null if pending)
declined_atstring/nullISO 8601 timestamp when declined (null if not declined)
userobjectContact information who filled the form
dataobjectForm field values keyed by field name
ratingstringOptional rating provided by the contact

User Object

FieldTypeDescription
emailstringContact email address
given_namestringContact first name
family_namestringContact last name
phonestringContact phone number
localestringLanguage used to fill the form (e.g., en, fr)

Completion Status

StatusDescriptionIndicators
PendingForm started but not submittedcompleted_at: null, declined_at: null
CompletedForm successfully submittedcompleted_at timestamp present, declined_at: null
DeclinedContact declined to fill the formcompleted_at: null, declined_at timestamp present

Finding Response IDs

Response IDs are included when you retrieve a form. Use the relationships to find responses:
// Get a form with its responses
const requestResponse = await fetch(
  `https://connect.penbox.io/v1/requests/${requestId}`,
  {
    headers: { 'Authorization': `Bearer ${accessToken}` }
  }
);

const { data, included } = await requestResponse.json();

// Extract response IDs from relationships
const responseIds = data.relationships.responses.data.map(r => r.id);

// Fetch each response
for (const responseId of responseIds) {
  const res = await fetch(
    `https://connect.penbox.io/v1/responses/${responseId}`,
    {
      headers: { 'Authorization': `Bearer ${accessToken}` }
    }
  );
  const responseData = await res.json();
  console.log('Response data:', responseData.data.attributes.data);
}

Accessing Form Data

The data attribute contains all form field values:
const { data } = await fetch(
  `https://connect.penbox.io/v1/responses/${responseId}`,
  { headers: { 'Authorization': `Bearer ${accessToken}` } }
).then(r => r.json());

const formData = data.attributes.data;

// Access specific fields
console.log('Company name:', formData.company_name);
console.log('Registration number:', formData.registration_number);

// Check completion status
const isCompleted = data.attributes.completed_at !== null;
const isDeclined = data.attributes.declined_at !== null;

Working with Uploaded Files

Responses include references to uploaded files in the included array:
const { data, included } = await fetch(
  `https://connect.penbox.io/v1/responses/${responseId}`,
  { headers: { 'Authorization': `Bearer ${accessToken}` } }
).then(r => r.json());

// Find files in the included array
const files = included.filter(item => item.type === 'attachments');

for (const file of files) {
  console.log('File:', file.attributes.name);
  console.log('Type:', file.attributes.type);
  console.log('Size:', file.attributes.metadata.size);

  // Download the file using the Files endpoint
  const fileUrl = `https://connect.penbox.io/v1/attachments/${file.id}`;
}
See Get File for download details.

Response Codes

CodeDescription
200Success - Response data retrieved
401Unauthorized - Invalid access token
403Forbidden - No access to this response
404Not Found - Response doesn’t exist
429Too Many Requests - Rate limit exceeded
500Server Error - Internal error
Responses are automatically created when a contact starts filling out a form. Initially, they contain partial data and no completion timestamp.
Once a response is completed (completed_at is set), it becomes immutable. You cannot modify the data or user information.

Authorizations

Authorization
string
header
required

OAuth2 access token. Include as: Authorization: Bearer {access_token}

Headers

Accept
enum<string>

Response format: application/json or application/pdf

Available options:
application/json,
application/pdf

Path Parameters

id
string<uuid>
required

Response UUID

Response

200 - application/json

Successful response

data
object

Deprecated: Use ResponseFlat instead

included
object[]