For AI agents: the documentation index is at /docs/payerbox/llms.txt. A Markdown version of this page is available at /docs/payerbox/api-reference/operations/member-consent-api.md or by requesting it with the Accept: text/markdown header.
Payerbox Docs

Member Consent Endpoints

The FHIR App Portal backend exposes two sets of endpoints for member consent capture:

  • Member endpoints, behind the Data Sharing page: read the member's choices, submit a choice, upload a representative's document of authority, and look up previous payers.
  • Admin endpoints, behind Consent Settings and Consent Reviews: the capture settings, the previous-payer registry, a member's consent overview, and review decisions.

A member submits a choice as the answers to one of two consent forms, as a FHIR QuestionnaireResponse. The portal writes the resulting records to the admin Aidbox. A Provider Access choice becomes a Consent conforming to the Da Vinci PDex STU 2.1 Provider Consent profile, and a Payer-to-Payer choice becomes an HRex STU 1.1 Consent. The answered form is kept as a US Core STU 6.1 QuestionnaireResponse (see Records written).

Endpoints

MethodPathCaller
GET/api/user-api/member/consentsMember
POST/api/user-api/member/consentsMember
POST/api/user-api/member/documentsMember
GET/api/user-api/member/previous-payersMember
GET, PUT/admin/consent/settingsAdmin
GET/admin/consent/previous-payersAdmin
GET/admin/consent/previous-payers/checkAdmin
POST/admin/consent/previous-payersAdmin
GET/admin/consent/members/{patientId}Admin
POST/admin/consent/reviews/{consentId}Admin

Paths are relative to the Admin Portal's host. Every endpoint answers 404 with consent_capture_off while the deployment does not enable member consent capture. On a read-only deployment the member write endpoints answer 403 with consent_capture_read_only.

Auth

  • Member endpoints: the member's portal session cookie, set when the member signs in to the portal. The signed-in user must be linked to a Patient, which is the only member the calls act for. Requests other than GET must also carry an X-Requested-With or X-Target-Portal header, which a cross-site form cannot set.
  • Admin endpoints: an admin-role portal session, or a Bearer token of the admin-api client obtained with client credentials.

See Authentication.

GET /api/user-api/member/consents

Everything the Data sharing page shows: the capture settings, both consent forms, and the member's consent records.

FieldTypeDescription
modestringread-write or read-only.
configuredbooleantrue when the plan organization and the Payer-to-Payer end date are set. Members can save choices only then.
patientIdstringThe Patient linked to the session.
organizationobject or nullThe plan organization: id, display.
p2pPeriodEnddate or nullEnd date of new Payer-to-Payer authorizations.
showNonSensitiveOptionbooleanWhether the Payer-to-Payer form offers the non-sensitive scope.
questionnairesobjectprovider-access and payer-to-payer: the two Questionnaire resources, or null where one is not loaded.
consentsConsent[]The member's consents for both switches, newest first.
responsesQuestionnaireResponse[]The answered forms.
documentsDocumentReference[]Consent documents and uploaded documents of authority.
provenancesProvenance[]Capture and review provenance.
relatedPersonsRelatedPerson[]Representatives who signed.

The lists hold only this feature's records: Consents with scope patient-privacy, consent documents with LOINC 59284-0, the forms they index, and representatives with the authority relationship codes the capture writes.

GET /api/user-api/member/consents
Cookie: <session cookie>
{
  "mode": "read-write",
  "configured": true,
  "patientId": "example-member",
  "organization": { "id": "example-health-plan", "display": "Example Health Plan" },
  "p2pPeriodEnd": "2027-12-31",
  "showNonSensitiveOption": true,
  "questionnaires": {
    "provider-access": { "resourceType": "Questionnaire", "url": "http://healthsamurai.io/fhir/Questionnaire/provider-access-member-opt-out", "version": "1.0.0", "...": "..." },
    "payer-to-payer": { "resourceType": "Questionnaire", "url": "http://healthsamurai.io/fhir/Questionnaire/p2p-member-consent", "version": "1.1.0", "...": "..." }
  },
  "consents": [{ "resourceType": "Consent", "id": "67d8623c-9af9-4dac-a40d-f5f30bb856ea", "status": "active", "...": "..." }],
  "responses": [],
  "documents": [],
  "provenances": [],
  "relatedPersons": []
}

POST /api/user-api/member/consents

Submits one choice: the answers to one of the two forms. The server fills the rest of the record from the session and the settings: subject, author, source, authored, status, the member block, the signature date and the Payer-to-Payer end date. Values the client sends for these are ignored.

Body

FieldCardinalityDescription
resourceType1..1QuestionnaireResponse
questionnaire1..1Canonical of one of the two forms, with or without |version.
item0..*The answered items, either nested in the form's groups or flat.
FormQuestionnaire URL
Provider Accesshttp://healthsamurai.io/fhir/Questionnaire/provider-access-member-opt-out
Payer-to-Payerhttp://healthsamurai.io/fhir/Questionnaire/p2p-member-consent

Answer codes are local to the forms and carry no system, except prior-plan-relationship.

linkIdFormAnswerRequired
sharing-choiceProvider AccessvalueCoding.code: share-all, opt-outYes
consent-choicePayer-to-PayervalueCoding.code: opt-in-full, opt-in-non-sensitive (only when offered), withdrawYes
prior-planPayer-to-PayerRepeating group, one per plan the member namesAt least one on an opt-in
prior-plan.prior-plan-organizationPayer-to-PayervalueReference to a registered previous payer, Organization/<id>Yes
prior-plan.prior-plan-member-idPayer-to-PayervalueStringNo
prior-plan.prior-plan-relationshipPayer-to-PayervalueCoding, system http://terminology.hl7.org/CodeSystem/subscriber-relationship: self, spouse, child, otherYes
prior-plan.prior-plan-kindPayer-to-PayervalueCoding.code: previous, concurrentYes
signer-relationshipBothvalueCoding.code: self, representativeYes
representative-nameBothvalueString, name and relationship to the memberFor a representative
representative-authorityBothvalueCoding.code: power-of-attorney, legal-guardian, otherFor a representative
representative-authority-otherBothvalueString describing the authorityWhen other
representative-docBothvalueAttachment returned by POST /api/user-api/member/documentsFor a representative
signer-signatureBothvalueAttachment with contentType image/png or image/jpeg and base64 dataYes

Response

201:

FieldDescription
questionnaireResponseIdThe stored form.
documentReferenceIdThe consent document that indexes it.
consentIdThe new Consent, or null for a Payer-to-Payer withdrawal, which writes no Consent.
consentStatusactive, draft for a representative's choice that shares more and waits for review, or null.
retiredHow many earlier records of the switch the save retired.

Examples

POST /api/user-api/member/consents
Cookie: <session cookie>
X-Requested-With: XMLHttpRequest
Content-Type: application/json

{
  "resourceType": "QuestionnaireResponse",
  "questionnaire": "http://healthsamurai.io/fhir/Questionnaire/provider-access-member-opt-out|1.0.0",
  "item": [
    { "linkId": "sharing-choice", "answer": [{ "valueCoding": { "code": "opt-out" } }] },
    { "linkId": "signer-relationship", "answer": [{ "valueCoding": { "code": "self" } }] },
    { "linkId": "signer-signature", "answer": [{ "valueAttachment": { "contentType": "image/png", "data": "iVBORw0KGgo...", "title": "signature.png" } }] }
  ]
}
{
  "questionnaireResponseId": "64ca24e1-e85a-48eb-8f56-85f815f3f058",
  "documentReferenceId": "23f02707-189f-40b7-a752-6f19cb37116b",
  "consentId": "67d8623c-9af9-4dac-a40d-f5f30bb856ea",
  "consentStatus": "active",
  "retired": 1
}
{
  "resourceType": "QuestionnaireResponse",
  "questionnaire": "http://healthsamurai.io/fhir/Questionnaire/p2p-member-consent|1.1.0",
  "item": [
    { "linkId": "consent-choice", "answer": [{ "valueCoding": { "code": "opt-in-full" } }] },
    { "linkId": "prior-plan", "item": [
      { "linkId": "prior-plan-organization", "answer": [{ "valueReference": { "reference": "Organization/lakeside-health-plan", "display": "Lakeside Health Plan" } }] },
      { "linkId": "prior-plan-member-id", "answer": [{ "valueString": "LHP-4471902" }] },
      { "linkId": "prior-plan-relationship", "answer": [{ "valueCoding": { "system": "http://terminology.hl7.org/CodeSystem/subscriber-relationship", "code": "self" } }] },
      { "linkId": "prior-plan-kind", "answer": [{ "valueCoding": { "code": "previous" } }] }
    ] },
    { "linkId": "signer-relationship", "answer": [{ "valueCoding": { "code": "self" } }] },
    { "linkId": "signer-signature", "answer": [{ "valueAttachment": { "contentType": "image/png", "data": "iVBORw0KGgo...", "title": "signature.png" } }] }
  ]
}
{
  "resourceType": "QuestionnaireResponse",
  "questionnaire": "http://healthsamurai.io/fhir/Questionnaire/provider-access-member-opt-out|1.0.0",
  "item": [
    { "linkId": "sharing-choice", "answer": [{ "valueCoding": { "code": "share-all" } }] },
    { "linkId": "signer-relationship", "answer": [{ "valueCoding": { "code": "representative" } }] },
    { "linkId": "representative-name", "answer": [{ "valueString": "Sam Lee, son" }] },
    { "linkId": "representative-authority", "answer": [{ "valueCoding": { "code": "power-of-attorney" } }] },
    { "linkId": "representative-doc", "answer": [{ "valueAttachment": { "url": "Binary/9a6f2c1e-4d3b-4e8a-9f5c-2b7d1e0a8c34", "contentType": "application/pdf", "title": "power-of-attorney.pdf" } }] },
    { "linkId": "signer-signature", "answer": [{ "valueAttachment": { "contentType": "image/png", "data": "iVBORw0KGgo...", "title": "signature.png" } }] }
  ]
}

The response has "consentStatus": "draft" and "retired": 0: the choice waits for an administrator, and the earlier one stays in force.

{ "error": "invalid_answers", "details": ["prior-plan: name at least one previous or concurrent health plan"] }
{
  "error": "consent_write_rejected",
  "message": "Sorry, we can't save it now. Please try again later or contact Member Services.",
  "detail": { "resourceType": "OperationOutcome", "issue": [{ "severity": "error", "diagnostics": "Referenced resource Patient/example-member content doesn't conform to any of target profiles: http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient" }] }
}

A save is one Aidbox transaction under the member's own token: the new records and the retirement of the earlier records of the same switch apply together or not at all. The message of every write error is written for the member.

POST /api/user-api/member/documents

Uploads a representative's document of authority before the form is submitted. The body is multipart/form-data with the file in the field file: a PDF, JPEG or PNG of up to 10 MB. The file is stored as a Binary whose securityContext is the member's Patient.

POST /api/user-api/member/documents
Cookie: <session cookie>
X-Requested-With: XMLHttpRequest
Content-Type: multipart/form-data; boundary=----form

------form
Content-Disposition: form-data; name="file"; filename="power-of-attorney.pdf"
Content-Type: application/pdf

<file bytes>
------form--
{ "url": "Binary/9a6f2c1e-4d3b-4e8a-9f5c-2b7d1e0a8c34", "contentType": "application/pdf", "title": "power-of-attorney.pdf", "size": 48211 }
{ "error": "unsupported_type", "allowed": ["application/pdf", "image/jpeg", "image/png"] }

Use the response as the representative-doc answer.

GET /api/user-api/member/previous-payers

The registered previous payers whose name contains q, at most 20, without the plan organization.

GET /api/user-api/member/previous-payers?q=lake
Cookie: <session cookie>
{ "payers": [{ "id": "lakeside-health-plan", "name": "Lakeside Health Plan", "npi": "1245319599", "active": true }] }

Reads and replaces the settings of Consent Settings. PUT takes organizationId, p2pPeriodEnd and showNonSensitiveOption, and answers like GET.

FieldTypeDescription
organizationIdstring or nullAidbox id of the plan's Organization. PUT refuses an id that matches no Organization.
p2pPeriodEnddate or nullYYYY-MM-DD, not in the past.
showNonSensitiveOptionbooleanDefault true.
organizationDisplaystring or nullResponse only: the Organization's name.
modestringResponse only: read-write or read-only.
sourcestringResponse only: defaults until the settings are saved once, then settings.
configuredbooleanResponse only: the organization and the end date are both set.
versionintegerResponse only: 1.
PUT /admin/consent/settings
Authorization: Bearer <admin-api token>
Content-Type: application/json

{ "organizationId": "example-health-plan", "p2pPeriodEnd": "2027-12-31", "showNonSensitiveOption": true }
{
  "version": 1,
  "source": "settings",
  "mode": "read-write",
  "organizationId": "example-health-plan",
  "organizationDisplay": "Example Health Plan",
  "p2pPeriodEnd": "2027-12-31",
  "showNonSensitiveOption": true,
  "configured": true
}
{ "error": "p2pPeriodEnd must not be in the past" }
EndpointDescription
GET /admin/consent/previous-payers?q=The registered previous payers, name order, at most 200, without the plan organization. Response: { "payers": [...] }.
GET /admin/consent/previous-payers/check?npi=Whether the NPI is well formed and whether a registered previous payer carries it. Response: { "npi", "valid", "existing": { "id", "name" } or null }.
POST /admin/consent/previous-payersRegisters a previous payer from { "name", "npi" }: an Organization declaring the HRex Organization profile, typed pay, with the NPI identifier and the previous-payer tag. Answers 201 with the new payer.
POST /admin/consent/previous-payers
Authorization: Bearer <admin-api token>
Content-Type: application/json

{ "name": "Summit Health", "npi": "1987654328" }
{ "id": "68efe1ee-1567-40e9-9698-e27ff7b2c3f6", "name": "Summit Health", "npi": "1987654328", "active": true }
{
  "error": "npi_exists",
  "message": "A previous payer with NPI 1987654328 is already registered: Summit Health. Nothing was created.",
  "existing": { "id": "68efe1ee-1567-40e9-9698-e27ff7b2c3f6", "name": "Summit Health" }
}

name is required, at most 200 characters; npi must be ten digits with a valid check digit. The NPI is unique among registered previous payers only. The create is conditional on the NPI and the tag, so two concurrent registrations cannot both succeed.

A member's consent overview, as the Data sharing card on Member Details shows it: the same consents, responses, documents, provenances, relatedPersons and questionnaires as the member endpoint, plus patientId, mode and pending, the choices waiting for review.

pending[] fieldDescription
consentIdThe draft Consent.
categoryprovider-access or payer-to-payer.
decisionpermit or deny.
scopePayer-to-Payer: all or nonsensitive; otherwise null.
dateTimeWhen the representative signed.
signername, authority, relatedPersonId.
authorityDocumenturl, contentType, title of the uploaded document, or null.
questionnaireResponseIdThe answered form.

POST /admin/consent/reviews/{consentId}

Approves or rejects a representative's draft.

FieldDescription
decisionapprove or reject.
noteOptional. Stored in the audit event only; longer notes are cut to 1,000 characters.
POST /admin/consent/reviews/0f617f31-1465-445d-8169-ef75832453f0
Authorization: Bearer <admin-api token>
Content-Type: application/json

{ "decision": "approve", "note": "Power of attorney checked" }
{ "consentId": "0f617f31-1465-445d-8169-ef75832453f0", "status": "active", "retired": 1 }
{ "error": "not_pending", "status": "active" }

An approval sets the Consent to active, adds its PDex or HRex profile, and retires the earlier records of the switch. A rejection sets it to rejected and changes nothing else. Both write a Provenance (activity UPDATE, agent type verifier) in the same FHIR transaction, with If-Match on every Consent.

Records written

One member save writes, in one transaction:

ResourceContent
QuestionnaireResponseThe answered form, US Core QuestionnaireResponse profile. subject is the member; author and source are the member or the representative.
DocumentReferenceThe consent document: LOINC 59284-0 Consent Document, attachment pointing to the QuestionnaireResponse, custodian the plan organization. HRex Consent requires a source document, so both forms get one.
DocumentReferenceRepresentatives only: the document of authority, type.text Personal representative authority document, attachment pointing to the uploaded Binary.
RelatedPersonRepresentatives only: US Core RelatedPerson profile, relationship POWATT, GUARD (v3-RoleCode) or RESP (v3-ParticipationType).
ConsentThe choice. None for a Payer-to-Payer withdrawal.
ProvenanceActivity CREATE and ONLINEWRIT; agents author (with onBehalfOf the member for a representative) and custodian; entity the form's canonical.

The Consent takes its shape from the switch:

ElementProvider AccessPayer-to-Payer
meta.profilehttp://hl7.org/fhir/us/davinci-pdex/StructureDefinition/pdex-provider-consenthttp://hl7.org/fhir/us/davinci-hrex/StructureDefinition/hrex-consent
categoryIDSCL and PDex API purpose provider-accessIDSCL and PDex API purpose payer-to-payer
provision.typedeny for an opt-out, permit to share againpermit
provision.periodstart = the day of the choicestart = the day of the choice, end = the settings' end date
provision.actorThe plan organization as performer; for a representative, also the RelatedPerson in their authority roleEach named plan as performer (source) and the plan organization as IRCP (recipient); for a representative, also the RelatedPerson in their authority role
policyNone#sensitive for all information, #regular for non-sensitive only
policyRulecricNone
performerThe member, also when a representative signsThe member, or the representative who signed

Records carry their profile only while active: a representative's draft has none until it is approved, and a retired or rejected record loses it. The profiles' canonical URLs carry no version.

Consent written for a Provider Access opt-out
{
  "resourceType": "Consent",
  "id": "67d8623c-9af9-4dac-a40d-f5f30bb856ea",
  "meta": {
    "profile": ["http://hl7.org/fhir/us/davinci-pdex/StructureDefinition/pdex-provider-consent"],
    "lastUpdated": "2026-10-06T14:22:00.959447Z"
  },
  "status": "active",
  "scope": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/consentscope", "code": "patient-privacy", "display": "Privacy Consent" }] },
  "category": [
    { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", "code": "IDSCL", "display": "information disclosure" }] },
    { "coding": [{ "system": "http://hl7.org/fhir/us/davinci-pdex/CodeSystem/pdex-consent-api-purpose", "code": "provider-access" }] }
  ],
  "patient": { "reference": "Patient/example-member" },
  "dateTime": "2026-10-06T14:22:00.000Z",
  "performer": [{ "reference": "Patient/example-member" }],
  "organization": [{ "reference": "Organization/example-health-plan" }],
  "sourceReference": { "reference": "DocumentReference/23f02707-189f-40b7-a752-6f19cb37116b" },
  "policyRule": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/consentpolicycodes", "code": "cric", "display": "Common Rule Informed Consent" }] },
  "provision": {
    "type": "deny",
    "period": { "start": "2026-10-06" },
    "actor": [{
      "role": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/provenance-participant-type", "code": "performer", "display": "Performer" }] },
      "reference": { "reference": "Organization/example-health-plan" }
    }],
    "action": [{ "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/consentaction", "code": "disclose", "display": "Disclose" }] }]
  }
}
Payer-to-Payer opt-in: the elements that differ
{
  "meta": { "profile": ["http://hl7.org/fhir/us/davinci-hrex/StructureDefinition/hrex-consent"] },
  "category": [
    { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", "code": "IDSCL" }] },
    { "coding": [{ "system": "http://hl7.org/fhir/us/davinci-pdex/CodeSystem/pdex-consent-api-purpose", "code": "payer-to-payer" }] }
  ],
  "policy": [{ "uri": "http://hl7.org/fhir/us/davinci-hrex/StructureDefinition-hrex-consent.html#sensitive" }],
  "provision": {
    "type": "permit",
    "period": { "start": "2026-10-06", "end": "2027-12-31" },
    "actor": [
      { "role": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/provenance-participant-type", "code": "performer" }] },
        "reference": { "reference": "Organization/lakeside-health-plan", "display": "Lakeside Health Plan" } },
      { "role": { "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/v3-ParticipationType", "code": "IRCP" }] },
        "reference": { "reference": "Organization/example-health-plan" } }
    ],
    "action": [{ "coding": [{ "system": "http://terminology.hl7.org/CodeSystem/consentaction", "code": "disclose" }] }]
  }
}

The earlier records of the same switch, active or draft, are retired in the same transaction: status becomes inactive and the PDex or HRex profile is removed, pinned with If-Match to the version read.

Errors

Member endpoints:

StatuserrorWhen
400invalid_json, invalid_body, unknown_questionnaireThe body is not JSON, not a QuestionnaireResponse with a questionnaire, or names another form. unknown_questionnaire lists the allowed canonicals.
400invalid_answersdetails lists what is wrong, such as a missing answer, an unknown item, a plan that is not a registered previous payer, or the non-sensitive option where it is not offered.
400invalid_multipart, file_required, empty_fileDocument upload without a usable file.
401Authentication required, Session expiredNo portal session, or an expired one.
403csrf_header_requiredA non-GET request without X-Requested-With or X-Target-Portal.
403not_a_memberThe signed-in user is not linked to a Patient.
403consent_capture_read_onlyA write on a read-only deployment.
403consent_write_forbiddenAidbox refused the write under the member's token.
404consent_capture_offMember consent capture is not enabled.
409consent_capture_not_configuredThe plan organization or the Payer-to-Payer end date is not set, or the organization is not found.
409consent_write_conflictA record changed between the read and the write; nothing was saved.
413file_too_largeThe document exceeds 10 MB (maxBytes).
415unsupported_typeThe document is not a PDF, JPEG or PNG.
422consent_write_rejectedAidbox rejected a record: detail holds its OperationOutcome.
500questionnaire_missingThe form is not loaded on the deployment.
502consent_lookup_failed, response_lookup_failed, document_lookup_failed, patient_lookup_failed, consent_save_failed, consent_write_failed, document_upload_failed, previous_payers_unavailableAidbox could not be read or written.

Admin endpoints:

StatuserrorWhen
400invalid_patient_id, invalid_consent_idThe id in the path is not a valid Aidbox id.
400A validation messageSettings, registration or review body problems, for example p2pPeriodEnd must not be in the past, Organization/<id> not found, Enter a valid 10-digit NPI, decision must be approve or reject.
401Authentication required, Invalid or expired tokenNo credentials, or credentials Aidbox does not accept.
403ForbiddenThe caller is neither an admin nor the admin-api client.
404consent_capture_off, not_foundCapture is not enabled, or the Consent does not exist or does not belong to this feature.
409npi_existsA registered previous payer already carries the NPI.
409not_pending, review_conflictThe Consent is no longer a draft, or a record changed during the review; nothing was saved.
500consent_without_patientThe draft has no patient reference.
502consent_lookup_failed, review_save_failed, consent_review_failed, and Failed to … messagesAidbox could not be read or written.

Current limitations

  • Member endpoints accept only portal sessions; there is no token-based access for members.

  • One plan organization per deployment.

  • The Consent and QuestionnaireResponse profiles name profiles as reference targets, so referenced records must declare those profiles in meta.profile, without a version:

    • the member's Patient: us-core-patient;
    • the plan organization and previous payers: hrex-organization;
    • a representative: us-core-relatedperson.

    The portal declares them on the previous payers and representatives it creates. Patients and the plan organization come from your data. A save that references a record without its declaration fails with 422 consent_write_rejected.

  • The non-sensitive Payer-to-Payer scope moves no data until sensitive data is labeled.

  • Previous payers cannot be renamed or removed through these endpoints.

  • Reads return up to 2,000 records of each type per member, newest first.

Last updated: