Documentation

Understanding the Persona API data model

Learn how the Persona API structures data using the JSON:API specification. This section explains data serialization, relationships, and how to optimize responses with sparse fieldsets. We'll walk through examples using the List all Inquiries endpoint.

Data organization overview

Persona’s API follows a consistent, portable data model:

  • Predictable: Each resource type (e.g., inquiryaccount) has a defined structure and attributes.
  • Implicit Relationships: Connected resources (e.g., inquiries and their verifications) are automatically linked and accessible via relationships.
  • Portable: API responses are standardized and compatible across environments.

This makes it easier to fetch individual resources, include related data, or streamline responses with filters.

Serialization

Serialization converts data into a consistent structure for transmission. Persona uses JSON:API to ensure every response is predictable and machine-readable.

Benefits:

  • Performance: Smaller, faster responses.
  • Privacy: Limit exposure to PII.
  • Clarity: Return only relevant data.

Data structure

Responses

All Persona APIresponses follow JSON:API specification:

  • data: the primary resource
  • included: related resources (optional)
  • meta: additional context (e.g., session tokens, pagination)

📘

Most endpoints that retrieve data—such as GET /inquiries/:id—do not require a request body.

data key

The data key contains an array of objects.

Each object contains:

  • type: The resource type, such as inquiry
  • id: A globally unique string that identifies the resource
  • attributes: An object of fields and values for that resource
  • relationships: References to related resources
# GET https://api.withpersona.com/api/v1/inquiries/ { "data": { "type": "inquiry", "id": "inq_2CVZ4HyVg7qaboXz2PUHknAn", "attributes": { "status": "approved", "reference-id": null, "created-at": "2019-09-09T22:40:56.000Z", "completed-at": "2019-09-09T22:44:51.000Z", "expired-at": null, "...": "..." }, "relationships": { "reports": { "data": [] }, "sessions": { "data": [] }, "template": { "data": { "id": "tmpl_JAZjHuAT738Q63BdgCuEJQre", "type": "template" } }, "verifications": { "data": [ { "id": "ver_KnqQRXmxmtquRE65CHTzymhR", "type": "verification/driver-license" }, { "id": "ver_2aguhcwq66zcmqipmrqjxw68", "type": "verification/selfie" } ] } }, }, "included": [ { "type": "template", "id": "tmpl_JAZjHuAT738Q63BdgCuEJQre", "attributes": { "name": "Acme #1" }, }, { "type": "verification/driver-license", "id": "ver_KnqQRXmxmtquRE65CHTzymhR", "attributes": { "status": "passed", "front-photo-url": "...", "created-at": "2019-09-09T22:41:29.000Z", "completed-at": "2019-09-09T22:41:40.000Z", "...": "..." }, }, { "type": "verification/selfie", "id": "ver_2aguhcwq66zcmqipmrqjxw68", "attributes": { "status": "passed", "center-photo-url": "...", "left-photo-url": "...", "right-photo-url": "...", "created-at": "2019-09-09T22:42:43.000Z", "completed-at": "2019-09-09T22:42:46.000Z", "...": "..." }, } ], "meta": { "session-token": "..." } }

attributes key

The attributes key includes all standard fields for a resource, including nested objects such as fields. By default, Persona returns the full attribute set.

To limit the fields returned, use sparse fieldsets: Sparse Fieldsets.

relationships key

The relationships key contains the type and id of related resources. These serve as lightweight pointers to objects listed in the included array (that may be fully returned if requested).

Relationships can be:

  • One-to-one: The data value is a single object with type and id
  • One-to-many: The data value is an array of objects

📘

All relationship keys (like verifications or template) are predefined and match what’s returned in the response schema. You do not have to define new ones.

included key

The included key contains fully serialized versions of related resources.

To include related resources in the response, use the include query parameter in your request. For example:

# GET https://api.withpersona.com/api/v1/inquiries/inq_2CVZ4HyVg7qaboXz2PUHknAn { "data": { "type": "inquiry", "id": "inq_2CVZ4HyVg7qaboXz2PUHknAn", "attributes": { "status": "approved", "reference-id": null, "created-at": "2019-09-09T22:40:56.000Z", "completed-at": "2019-09-09T22:44:51.000Z", "expired-at": null, "...": "..." }, "relationships": { "reports": { "data": [] }, "sessions": { "data": [] }, "template": { "data": { "id": "tmpl_JAZjHuAT738Q63BdgCuEJQre", "type": "template" } }, "verifications": { "data": [ { "id": "ver_KnqQRXmxmtquRE65CHTzymhR", "type": "verification/driver-license" }, { "id": "ver_2aguhcwq66zcmqipmrqjxw68", "type": "verification/selfie" } ] } }, }, "included": [ { "type": "template", "id": "tmpl_JAZjHuAT738Q63BdgCuEJQre", "attributes": { "name": "Acme #1" }, }, { "type": "verification/driver-license", "id": "ver_KnqQRXmxmtquRE65CHTzymhR", "attributes": { "status": "passed", "front-photo-url": "...", "created-at": "2019-09-09T22:41:29.000Z", "completed-at": "2019-09-09T22:41:40.000Z", "...": "..." }, }, { "type": "verification/selfie", "id": "ver_2aguhcwq66zcmqipmrqjxw68", "attributes": { "status": "passed", "center-photo-url": "...", "left-photo-url": "...", "right-photo-url": "...", "created-at": "2019-09-09T22:42:43.000Z", "completed-at": "2019-09-09T22:42:46.000Z", "...": "..." }, } ], "meta": { "session-token": "..." } }
# GET https://api.withpersona.com/api/v1/inquiries/inq_2CVZ4HyVg7qaboXz2PUHknAn?include= { "data": { "type": "inquiry", "id": "inq_2CVZ4HyVg7qaboXz2PUHknAn", "attributes": { "status": "approved", "reference-id": null, "created-at": "2019-09-09T22:40:56.000Z", "completed-at": "2019-09-09T22:44:51.000Z", "expired-at": null, "...": "..." }, "relationships": { "reports": { "data": [] }, "sessions": { "data": [] }, "template": { "data": { "id": "tmpl_JAZjHuAT738Q63BdgCuEJQre", "type": "template" } }, "verifications": { "data": [ { "id": "ver_KnqQRXmxmtquRE65CHTzymhR", "type": "verification/driver-license" }, { "id": "ver_2aguhcwq66zcmqipmrqjxw68", "type": "verification/selfie" } ] } }, }, "included": [], "meta": { "session-token": "..." } }
# GET https://api.withpersona.com/api/v1/inquiries/inq_2CVZ4HyVg7qaboXz2PUHknAn?include=verifications { "data": { "type": "inquiry", "id": "inq_2CVZ4HyVg7qaboXz2PUHknAn", "attributes": { "status": "approved", "reference-id": null, "created-at": "2019-09-09T22:40:56.000Z", "completed-at": "2019-09-09T22:44:51.000Z", "expired-at": null, "...": "..." }, "relationships": { "reports": { "data": [] }, "sessions": { "data": [] }, "template": { "data": { "id": "tmpl_JAZjHuAT738Q63BdgCuEJQre", "type": "template" } }, "verifications": { "data": [ { "id": "ver_KnqQRXmxmtquRE65CHTzymhR", "type": "verification/driver-license" }, { "id": "ver_2aguhcwq66zcmqipmrqjxw68", "type": "verification/selfie" } ] } }, }, "included": [ { "type": "verification/driver-license", "id": "ver_KnqQRXmxmtquRE65CHTzymhR", "attributes": { "status": "passed", "front-photo-url": "...", "created-at": "2019-09-09T22:41:29.000Z", "completed-at": "2019-09-09T22:41:40.000Z", "...": "..." }, }, { "type": "verification/selfie", "id": "ver_2aguhcwq66zcmqipmrqjxw68", "attributes": { "status": "passed", "center-photo-url": "...", "left-photo-url": "...", "right-photo-url": "...", "created-at": "2019-09-09T22:42:43.000Z", "completed-at": "2019-09-09T22:42:46.000Z", "...": "..." }, } ], "meta": { "session-token": "..." } }

This will populate the included array with the full verification objects related to the primary resource.

📘

The include parameter is not supported on "list all" endpoints (e.g., GET /inquiries). If used, the API will return a 400 Bad Request error.

When you can useincluded

The included parameter must reference relationships defined on the resource. Specifically:

  • Only relationships that appear as keys under therelationships object in the response can be included.
  • If a relationship does not appear in relationships, it cannot be requested via included.

📘

You can think of relationships as a map of which related resources are available. The include parameter tells the API which of those to fully serialize into the included array.

Nested include relationships

You can include one level of nested relationships using dot notation:

?include=foo.bar ✅ ?include=foo.bar.baz ❌ (Too deep—returns 400)

Comma-separated values include multiple relationships:

?include=foo,bar

Dot-separated paths allow limited nesting:

?include=foo.bar

meta key

This key contains metadata not tied to the resource model. You’ll commonly see:

  • Pagination data
  • Session tokens
  • Operation-specific info