GAP Partner API – Implementation Guidance

1. Introduction

API Overview and Purpose

The GAP Partner API provides a FHIR R4 interface allowing authorized partners to submit GAP service requests to the platform.

Partners create a request by sending a FHIR Bundle containing patient information, orientation data from the Vitrai system, and request provenance.

FHIR profiles referenced in this guide are defined separately in the FHIR Artifacts folder of this Implementation Guide.


2. Authentication & Security

Authentication Method

The API uses JWT (JSON Web Token) authentication via Keycloak to secure access to endpoints.

Required configuration

Partners must obtain a valid JWT token from the configured Keycloak server.

The token must be included in the Authorization header of each request in the following format:

Authorization: Bearer

Example request header

Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

Requests without valid authentication will return 401 Unauthorized.


3. Creating a GAP Request

POST /gap/demandes/Bundle

Creates a GAP request using a FHIR Bundle.

Description

Creates a new GAP request by submitting a FHIR Bundle of type transaction containing the required resources.

Authentication

JWT Bearer Token required.

Accepted format

Content-Type: application/json

Bundle type

Bundle.type = transaction


4. Required FHIR Resources

The Bundle must contain the following resources conforming to the GAP FHIR profiles defined in this Implementation Guide.

Patient (Required)

The Patient resource contains basic demographic information.

Required fields

  • name[0].use = official
  • name[0].family – Last name
  • name[0].given[0] – First name
  • birthDate – Format YYYY-MM-DD
  • gendermale | female | other
  • address[0].postalCode
  • telecom – at least one phone number
    • system = phone
    • value = 10-digit number
    • use = mobile | home
    • rank = 1 → indicates preferred SMS communication
  • communication[0]
    • language.coding[0].code
    • Allowed values: fr, fr-CA, en, en-CA
    • preferred = true

Optional fields

Email contact:

telecom.system = email

Email becomes required when:

  • the patient initiates the request, and
  • the preferred communication method is email.

NAM Identifier (Optional)

identifier[0].system = https://ramq.gouv.qc.ca/id/nam identifier[0].value = NAM identifier[0].period.end = expiration date

Expiration date is required when NAM is provided.

NAM rule

Condition Requirement
NAM provided Parent RelatedPerson resources optional
NAM missing Both MTH and FTH RelatedPerson resources required

RelatedPerson (Conditional)

Represents individuals related to the patient such as parents or authorized representatives.


A) Parent (MTH / FTH)

Required only if the Patient does not have a NAM.

Required fields

relationship.coding.system = http://terminology.hl7.org/CodeSystem/v3-RoleCode relationship.coding.code = MTH | FTH name[0].use = official name[0].family name[0].given[0]

patient.reference

Optional fields

  • telecom
  • communication

B) Representative / Contact (DELEGATEE)

Represents an authorized contact for the patient.

Required fields

  • relationship must include at least one code
  • If DELEGATEE exists, the RelatedPerson is treated as a contact
  • A second code defines the relationship (e.g. MTH, FTH, GUARD)

Required data:

  • name
  • at least one phone number
  • patient.reference
  • communication[0] (language + preferred)

Optional fields

Email contact:

telecom.system = email

Contact extraction rule

The system extracts the first relationship code that is not DELEGATEE.

contactRepresentative = true

when the DELEGATEE code is present.


Provenance (Required)

The Provenance resource is mandatory for all GAP requests.

Required fields

resourceType = Provenance

meta.profile = http://akinox.com/fhir/StructureDefinition/gap-provenance-profile

target.reference = Bundle/

recorded = ISO-8601 timestamp

agent[0]

Author reference

Patient initiated request:

Patient/

Representative initiated request:

RelatedPerson/

If the Provenance resource is missing or invalid, the API returns:

422 Unprocessable Content


4. FHIR Data Format

The API uses FHIR R4 for all data exchanges.

Bundle structure

Element Description
type transaction
identifier Unique request identifier
timestamp Bundle creation timestamp
entry List of FHIR resources

All resources must conform to the GAP FHIR profiles defined in this Implementation Guide.

Profiles enforce:

  • Required fields
  • Identifier formats (e.g., NAM)
  • Terminology bindings
  • GAP-specific extensions

5. Error Management

The API returns standard HTTP codes with FHIR OperationOutcome responses.

HTTP Status Codes

Code Meaning
201 Request successfully created
400 Invalid payload
401 Missing or invalid authentication
403 Access denied
422 FHIR validation or business rule error
429 Rate limit exceeded
500 Internal server error
503 Service unavailable

OperationOutcome Structure

{
  "resourceType": "OperationOutcome",
  "issue": [
    {
      "severity": "error",
      "code": "invalid",
      "details": {
        "text": "Patient resource is missing required field: firstName"
      }
    }
  ]
}

Example Errors:

Timeout

{
  "resourceType": "OperationOutcome",
  "issue": [
    {
      "severity": "error",
      "code": "timeout",
      "details": {
        "text": "Request has timed out, please try again"
      }
    }
  ]
}

Communication Error

{
  "resourceType": "OperationOutcome",
  "issue": [
    {
      "severity": "error",
      "code": "exception",
      "details": {
        "text": "An error occurred while sending the request"
      }
    }
  ]
}

Missing Bundle

{
  "resourceType": "OperationOutcome",
  "issue": [
    {
      "severity": "error",
      "code": "invalid",
      "details": {
        "text": "Bundle payload is required"
      }
    }
  ]
}

Missing Required Field

{
  "resourceType": "OperationOutcome",
  "issue": [
    {
      "severity": "error",
      "code": "required",
      "details": {
        "text": "Patient resource is missing required field: firstName"
      }
    }
  ]
}

Business Rule Error

{
  "resourceType": "OperationOutcome",
  "issue": [
    {
      "severity": "error",
      "code": "business-rule",
      "details": {
        "text": "When NAM is not provided, both mother (MTH) and father (FTH) RelatedPerson resources are required"
      }
    }
  ]
}

Profile Validation Error

{
  "resourceType": "OperationOutcome",
  "issue": [
    {
      "severity": "error",
      "code": "structure",
      "details": {
        "text": "Task resource does not conform to expected GAP profile"
      }
    }
  ]
}

Successful Response

{
  "resourceType": "OperationOutcome",
  "issue": [
    {
      "severity": "information",
      "code": "informational",
      "details": {
        "text": "GAP request has been successfully created and queued for processing"
      }
    }
  ]
}