Getting Started

This page outlines how to use our SDKs to interact with our API. Specifically, you’ll learn how to make a request to create an Encounter.

SDK Information

If your language of choice is not yet supported, you can still use our API by making requests directly to our REST endpoints. For further questions or to ask for additional language support, please reach out to our Support team.

Prerequisites

  • Python 3, Node, or Ruby 2.7+ installed on your system
  • Candid Client ID
  • Candid Client Secret

Installation

First, install the SDK using your package manager:

$pip install candidhealth # or poetry install, etc

Authentication

To make requests to our API, you’ll need to use your API key for authentication. Initialize the SDK as follows:

1from candid.client import CandidApiClient
2from candid.environment import CandidApiEnvironment
3
4client = CandidApiClient(
5 environment=CandidApiEnvironment.STAGING,
6 options=CandidApiClientOptions(
7 client_id="YOUR_CLIENT_ID",
8 client_secret="YOUR_CLIENT_SECRET"
9 )
10)

Candid provides two environments, staging and production. Take care to pass the correct environment when creating your API client so that requests are routed correctly. Be sure to not send PHI to the staging environment.

Making an Example Request

In this example, we’ll create an Encounter using the V4 API.

1created_encounter = client.encounters.v_4.create(
2 external_id=EncounterExternalId("emr-claim-id-abcd"),
3 date_of_service=Date("2023-05-23"),
4 billable_status=BillableStatusType.BILLABLE, # or BillableStatusType.NOT_BILLABLE
5 responsible_party=ResponsiblePartyType.INSURANCE_PAY, # or ResponsiblePartyType.SELF_PAY
6 patient=PatientCreate(
7 external_id="emr-patient-id-123",
8 first_name="Loki",
9 last_name="Laufeyson",
10 date_of_birth=Date("1983-12-17"),
11 gender=Gender.MALE,
12 address=StreetAddressShortZip(
13 address_1="1234 Main St",
14 address_2="Apt 9876",
15 city="Asgard",
16 state=State.CA,
17 zip_code="94109",
18 zip_plus_four_code="1234",
19 ),
20 ),
21 patient_authorized_release=True,
22 billing_provider=BillingProvider(
23 organization_name="Acme Health PC",
24 npi="1234567890",
25 tax_id="123456789",
26 address=StreetAddressLongZip(
27 address_1="1234 Main St",
28 address_2="Apt 9876",
29 city="Asgard",
30 state=State.CA,
31 zip_code="94109",
32 zip_plus_four_code="1234",
33 ),
34 ),
35 rendering_provider=RenderingProvider(
36 first_name="Doctor",
37 last_name="Strange",
38 npi="9876543210",
39 ),
40 diagnoses=[
41 DiagnosisCreate(code_type=DiagnosisTypeCode.ABF, code="Z63.88"),
42 DiagnosisCreate(code_type=DiagnosisTypeCode.ABF, code="E66.66"),
43 ],
44 place_of_service_code=FacilityTypeCode.TELEHEALTH,
45 service_lines=[
46 ServiceLineCreate(
47 procedure_code="99212",
48 modifiers=[],
49 quantity=Decimal("1.0"),
50 units=ServiceLineUnits.UN,
51 charge_amount_cents=1500,
52 diagnosis_pointers=[0, 1],
53 ),
54 ],
55 clinical_notes=[],
56 provider_accepts_assignment=True,
57 benefits_assigned_to_provider=True,
58)

Error Handling

Each endpoint in our SDK documents which errors and exceptions can be raised if the request fails. These can be caught and handled via native exception-handling:

1from candid.resources.encounters.resources.v_4.errors import EncounterExternalIdUniquenessError
2
3try:
4 created_encounter = client.encounters.v_4.create(...)
5except EncounterExternalIdUniquenessError as e:
6 print(f"An error occurred: {e}")

Rate Limiting

Requests to the Candid API are rate-limited by IP. Each IP is allowed 1000 requests within a 10-second rolling window.

If an IP exceeds its limit, the API will respond with HTTP 429 - Too Many Requests. If this occurs, it is recommended that the client retry the request with exponential backoff logic to reduce request volume density. Exponential backoff logic is already implemented inside the Candid Health SDKs.

Full Source Code

1from candid.candid_api_client import CandidApiClient, CandidApiClientOptions
2from candid import (
3 CandidApiEnvironment,
4 EncounterExternalId,
5 Date,
6 PatientCreate,
7 Gender,
8 StreetAddressShortZip,
9 State,
10 StreetAddressLongZip,
11 DiagnosisCreate,
12 DiagnosisTypeCode,
13 FacilityTypeCode,
14 ServiceLineCreate,
15 ServiceLineUnits,
16 Decimal,
17)
18from candid.resources.encounter_providers.resources.v_2 import BillingProvider, RenderingProvider
19from candid.resources.encounters.resources.v_4 import BillableStatusType, ResponsiblePartyType
20
21client = CandidApiClient(
22 environment=CandidApiEnvironment.STAGING,
23 options=CandidApiClientOptions(
24 client_id="YOUR_CLIENT_ID",
25 client_secret="YOUR_CLIENT_SECRET"
26 )
27)
28
29created_encounter = client.encounters.v_4.create(
30 external_id=EncounterExternalId("emr-claim-id-abcd"),
31 date_of_service=Date("2023-05-23"),
32 billable_status=BillableStatusType.BILLABLE, # or BillableStatusType.NOT_BILLABLE
33 responsible_party=ResponsiblePartyType.INSURANCE_PAY, # or ResponsiblePartyType.SELF_PAY
34 patient=PatientCreate(
35 external_id="emr-patient-id-123",
36 first_name="Loki",
37 last_name="Laufeyson",
38 date_of_birth=Date("1983-12-17"),
39 gender=Gender.MALE,
40 address=StreetAddressShortZip(
41 address_1="1234 Main St",
42 address_2="Apt 9876",
43 city="Asgard",
44 state=State.CA,
45 zip_code="94109",
46 zip_plus_four_code="1234",
47 ),
48 ),
49 patient_authorized_release=True,
50 billing_provider=BillingProvider(
51 organization_name="Acme Health PC",
52 npi="1234567890",
53 tax_id="123456789",
54 address=StreetAddressLongZip(
55 address_1="1234 Main St",
56 address_2="Apt 9876",
57 city="Asgard",
58 state=State.CA,
59 zip_code="94109",
60 zip_plus_four_code="1234",
61 ),
62 ),
63 rendering_provider=RenderingProvider(
64 first_name="Doctor",
65 last_name="Strange",
66 npi="9876543210",
67 ),
68 diagnoses=[
69 DiagnosisCreate(code_type=DiagnosisTypeCode.ABF, code="Z63.88"),
70 DiagnosisCreate(code_type=DiagnosisTypeCode.ABF, code="E66.66"),
71 ],
72 place_of_service_code=FacilityTypeCode.TELEHEALTH,
73 service_lines=[
74 ServiceLineCreate(
75 procedure_code="99212",
76 modifiers=[],
77 quantity=Decimal("1.0"),
78 units=ServiceLineUnits.UN,
79 charge_amount_cents=1500,
80 diagnosis_pointers=[0, 1],
81 ),
82 ],
83 clinical_notes=[],
84 provider_accepts_assignment=True,
85 benefits_assigned_to_provider=True,
86)