Skip to content

Commit 62f4b0f

Browse files
authored
Update README.md
1 parent 48c5a2d commit 62f4b0f

File tree

1 file changed

+220
-5
lines changed

1 file changed

+220
-5
lines changed

README.md

Lines changed: 220 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
# Inbox Health Partner API
32

43
This document is meant to accompany and provide a user-friendly overview of the full specifications of the Inbox Health Partner REST API, fully-documented at [rest.demo.inboxhealth.com/api](https://rest.demo.inboxhealth.com/api). Reading and understand the data model and endpoints outlined by those full specifications is recommended.
@@ -13,12 +12,14 @@ The full specification of the Inbox Health Partner REST API documentation is ava
1312
In order for your request to be properly authenticated, you will need to supply your API Key as a header in each request you send. Simply add the API Key you generated via the Partner portal above to each HTTP request in a `x-api-key` header.
1413

1514
## Rate Limiting
16-
By default, all Partner API users are assigned a Basic Partner usage plan that is rate limited to 1 request per second, with an available burst rate of 40 requests per second.
15+
By default, all Partner API users are assigned a Basic Partner usage plan that is rate limited to 1 request per second, with an available burst rate of 40 requests per second. If this limit is exceeded, your request will not be processed by the application servers in any way and the Inbox Health API will return a HTTP error code of 429, "Too Many Requests". If this error is encountered, please retry your request and/or build in a client-side rate-limiter to prevent unnecessary extra requests.
1716

1817
## Onboarding New Clients
1918

2019
### Creating an Enterprise
21-
The "Enterprise" model is the central record in Inbox Health's API Entities that represents a new customer seeking to bill their patients (whether it is a Hospital, Medical Practice, Therapy Group, or other medical organization). Thus, the first step to onboarding a new client to the Inbox Health platform is to create their Enterprise record that corresponds to their business and will serve to define many of the basic properties. For now, we will review creating a basic Enterprise with one sub "Practice" (facility) and let Inbox Health set many of the default properties for us. Send the following HTTP Request to the Enterprise POST endpoint available at [api.demo.inboxhealth.com/partner/v2/enterprises](http://api.demo.inboxhealth.com/partner/v2/enterprises)
20+
The "Enterprise" model is the central record in Inbox Health's API Entities that represents a new customer seeking to bill their patients (whether it is a Hospital, Medical Practice, Therapy Group, or other medical organization). Thus, the first step to onboarding a new client to the Inbox Health platform is to create their Enterprise record that corresponds to their business and will serve to define many of the basic properties. For now, we will review creating a basic Enterprise with one sub "Practice" (facility) and let Inbox Health set many of the default properties for us. If you omit `practice_attributes`, or send an empty array, we will create a seed practice for you using the attributes from the enterprise.
21+
22+
Send the following HTTP Request to the Enterprise POST endpoint available at [api.demo.inboxhealth.com/partner/v2/enterprises](http://api.demo.inboxhealth.com/partner/v2/enterprises)
2223

2324
JSON Body:
2425

@@ -276,7 +277,11 @@ This section covers how to create new Invoice, LineItem, and Payment records to
276277
This section covers how to define new BillingCycleTemplates, control existing BillingCycles, and send out-of-band communication such a Patient Tickets (SMS, email, and automated voice calls)
277278

278279
## Subscribing to Webhooks
279-
This section covers how to receive dynamic updates from Inbox Health via REST API webhooks that ensure API clients are immediately informed upon changes of relevant records in Inbox Health. Whether the change originates from a patient, provider, administrator or automated system these webhooks are triggered and immediately provide feedback
280+
This section covers how to receive dynamic updates from Inbox Health via REST API webhooks that ensure API clients are immediately informed upon changes of relevant records in Inbox Health. Whether the change originates from a patient, provider, administrator or automated system these webhooks are triggered and immediately provide feedback.
281+
282+
### Invoice Updated Webhook
283+
284+
When updating parent properties of an invoice (the date of service, for example), you will receive an invoice updated webhook event. However, when adding line items or invoice payments to an invoice, that will not trigger an invoice updated webhook event. Instead, you will receive the line item/invoice payment created webhook events.
280285

281286
## X-InboxHealth-Signature Header
282287
This section will explain the steps required to reproduce the header X-InboxHealth-Signature which is used to verify that all webhook event requests coming from Inbox Health are authentic and haven’t been tampered with. The X-InboxHealth-Signature header is generated using the HMAC-SHA1 hashing algorithm, with the base signature being generated from the request URL and the POST body parameters, using your secret API key as the signing key.
@@ -397,7 +402,217 @@ https://coolcompany.com/api/v1/webhookscreated_at=2019-08-29T12%3A06%3A53.000-04
397402
and using an example API key of `api_key` as our signing key, the X-InboxHealth-Signature would be
398403

399404
`93G+w7p0GC2FB+us2KO8lT/XfZM=`
400-
405+
406+
## A Fully Working C# Example of Onboarding a New Enterprise
407+
```
408+
using Newtonsoft.Json;
409+
using Newtonsoft.Json.Linq;
410+
using RestSharp;
411+
using System;
412+
using System.Collections.Generic;
413+
using System.Linq;
414+
415+
namespace InboxHealthExamples
416+
{
417+
/**
418+
* Here's an example using purely RestSharp to call the Partner API.
419+
*/
420+
class Rest
421+
{
422+
static void Main(string[] args) {
423+
var client = new RestClient("http://localhost/partner/v2");
424+
client.AddDefaultHeader("x-api-key", "YOUR_API_KEY");
425+
client.Timeout = -1;
426+
427+
/**
428+
* The "Enterprise" model is the central record in Inbox Health's API Entities
429+
* that represents a new customer seeking to bill their patients
430+
* (whether it is a Hospital, Medical Practice, Therapy Group, or other medical organization).
431+
* Thus, the first step to onboarding a new client to the Inbox Health platform is to
432+
* create their Enterprise record that corresponds to their business and will serve to define
433+
* many of the basic properties. For now, we will review creating a basic Enterprise
434+
* with one sub "Practice" (facility) and let Inbox Health set many of the default properties for us.
435+
*/
436+
var enterpriseRoot = new {
437+
enterprise = new {
438+
name = Faker.Company.Name(),
439+
address_line_1 = Faker.Address.StreetAddress(),
440+
city = Faker.Address.City(),
441+
state = Faker.Address.UsStateAbbr(),
442+
zip = Faker.Address.ZipCode(),
443+
sales_tax = 6.35m,
444+
time_zone = "Eastern Time (US & Canada)",
445+
support_phone_number = "(203) 415-3486",
446+
default_quick_pay_description = "Copay",
447+
statement_descriptor = "LIVE FROM REST",
448+
return_envelope = true,
449+
perforation = true,
450+
practices_attributes = new List<object> {
451+
new {
452+
name = Faker.Company.Name(),
453+
address_line_1 = Faker.Address.StreetAddress(),
454+
city = Faker.Address.City(),
455+
state = Faker.Address.UsStateAbbr(),
456+
zip = Faker.Address.ZipCode(),
457+
time_zone = "Eastern Time (US & Canada)"
458+
}
459+
}
460+
}
461+
};
462+
var request = new RestRequest("enterprises", DataFormat.Json);
463+
request.AddJsonBody(enterpriseRoot);
464+
var response = client.Post(request);
465+
var enterpriseJObject = JsonConvert.DeserializeObject<JObject>(response.Content);
466+
Console.WriteLine(enterpriseJObject.ToString());
467+
468+
/**
469+
* Now that the enterprise record has been created, store the enterprise.id field,
470+
* as this will serve as the unique identifier for this record,
471+
* and form the basis for many other requests for associated records.
472+
*/
473+
int enterpriseId = (int)enterpriseJObject["enterprise"]["id"];
474+
475+
/**
476+
* We're now ready to create a handful of Patient records.
477+
* These patients will serve as the central records to attach future Invoices (charges) and Payments.
478+
* Patient records act similar to Customer objects seen in other invoicing platforms
479+
* and are tracked individually; their balances and properties along with the Enterprise's settings
480+
* and the Enterprise's defined BillingCycleTemplates,
481+
* govern how and when Inbox Health sends the Patient statements and communication.
482+
*/
483+
for (int i = 0; i < 10; ++i) {
484+
request = new RestRequest("patients", DataFormat.Json);
485+
var patientRoot = new {
486+
patient = new {
487+
enterprise_id = enterpriseId,
488+
first_name = Faker.Name.First(),
489+
last_name = Faker.Name.Last(),
490+
date_of_birth = "1980-01-01",
491+
email = Faker.Internet.Email(),
492+
phone = Faker.Phone.Number(),
493+
address_line_1 = Faker.Address.StreetAddress(),
494+
city = Faker.Address.City(),
495+
state = Faker.Address.UsStateAbbr(),
496+
zip = Faker.Address.ZipCode()
497+
}
498+
};
499+
request.AddJsonBody(patientRoot);
500+
response = client.Post(request);
501+
502+
Console.WriteLine(JsonConvert.DeserializeObject<JObject>(response.Content).ToString());
503+
}
504+
505+
/**
506+
* The next step in onboarding would be to start importing doctors.
507+
* Primarily, doctors will be referenced on invoices.
508+
*/
509+
for (int i = 0; i < 10; ++i) {
510+
request = new RestRequest("doctors", DataFormat.Json);
511+
var doctorRoot = new {
512+
doctor = new {
513+
enterprise_id = enterpriseId,
514+
first_name = Faker.Name.First(),
515+
last_name = Faker.Name.Last(),
516+
phone = Faker.Phone.Number(),
517+
specialty = "General Physician",
518+
email = Faker.Internet.Email(),
519+
suffix = "M.D.",
520+
npi = "1234567890"
521+
}
522+
};
523+
request.AddJsonBody(doctorRoot);
524+
response = client.Post(request);
525+
526+
Console.WriteLine(JsonConvert.DeserializeObject<JObject>(response.Content).ToString());
527+
}
528+
529+
var doctors = JsonConvert.DeserializeObject<JObject>(client.Get(new RestRequest("enterprises/{id}/doctors").AddParameter("id", enterpriseId, ParameterType.UrlSegment)).Content);
530+
Console.WriteLine(doctors.ToString());
531+
532+
/**
533+
* We can now get to the fun part! Let's start adding invoices for our patients.
534+
* Invoices are the central vehicle for creating patient balances.
535+
* Invoices contain line items, which tell us not only the procedure/service performed,
536+
* but what's the total charge, how much is covered by insurance
537+
* and how much is still owed by insurance for that line item.
538+
*/
539+
var practices = JsonConvert.DeserializeObject<JObject>(client.Get(new RestRequest("enterprises/{id}/practices").AddParameter("id", enterpriseId, ParameterType.UrlSegment)).Content);
540+
var patients = JsonConvert.DeserializeObject<JObject>(client.Get(new RestRequest("enterprises/{id}/patients").AddParameter("id", enterpriseId, ParameterType.UrlSegment)).Content);
541+
foreach (JObject patient in patients["patients"]) {
542+
request = new RestRequest("invoices", DataFormat.Json);
543+
/**
544+
* Our test invoices will simply contain one line item each, where
545+
* insurance owed amount cents is 0, translating the remaining balance (charge - covered) into
546+
* a balance that is now the patient's responsibility.
547+
* If insurance owed amount cents was any value greater than 0,
548+
* the invoice would not count towards the patient's total balance yet.
549+
*/
550+
var invoiceRoot = new {
551+
invoice = new {
552+
patient_id = (int)patient["id"],
553+
practice_id = (int)practices["practices"][0]["id"],
554+
date_of_service = DateTime.Now.ToString("yyyy-MM-dd"),
555+
doctor_id = (int)doctors["doctors"][0]["id"],
556+
notes = "What a wonderful patient!",
557+
estimate = false,
558+
line_items_attributes = new[] {
559+
new {
560+
description = "A medical procedure",
561+
date_of_service = DateTime.Now.ToString("yyyy-MM-dd"),
562+
total_charge_amount_cents = new Random().Next(1000, 10000),
563+
covered_amount_cents = new Random().Next(100, 500),
564+
service_code = "Y93C9",
565+
tax_amount_cents = 10,
566+
quantity = 1,
567+
insurance_owed_amount_cents = 0
568+
}
569+
}
570+
}
571+
};
572+
request.AddJsonBody(invoiceRoot);
573+
response = client.Post(request);
574+
575+
Console.WriteLine(JsonConvert.DeserializeObject<JObject>(response.Content).ToString());
576+
}
577+
578+
/**
579+
* We can re-get our patients to see their updated balances.
580+
*/
581+
patients = JsonConvert.DeserializeObject<JObject>(client.Get(new RestRequest("enterprises/{id}/patients").AddParameter("id", enterpriseId, ParameterType.UrlSegment)).Content);
582+
patients["patients"].ToList().ForEach(p => Console.WriteLine("Patient id " + p["id"] + " has a balance of " + p["balance_cents"]));
583+
584+
/**
585+
* And now we can start importing payments. When importing payments, you need to specify the payment method type.
586+
*
587+
* external_card = A card payment made outside of Inbox Health, such as an historical card payment made prior to integrating with Inbox Health.
588+
* card = An Inbox Health card payment, using a saved payment method, that will be processed through Stripe.
589+
* one_time_payment = An Inbox Health card payment, using a Stripe one-time token, that will be processed through Stripe.
590+
*
591+
* For initial onboarding, when importing existing, already processed card payments, you use external_card.
592+
*/
593+
request = new RestRequest("payments", DataFormat.Json);
594+
var paymentRoot = new {
595+
payment = new {
596+
patient_id = (int)patients["patients"][0]["id"],
597+
expected_amount_cents = (int)patients["patients"][0]["balance_cents"],
598+
payment_method_type = "external_card"
599+
}
600+
};
601+
request.AddJsonBody(paymentRoot);
602+
response = client.Post(request);
603+
604+
Console.WriteLine(JsonConvert.DeserializeObject<JObject>(response.Content).ToString());
605+
606+
/**
607+
* And now the patient's balance is updated to $0.
608+
*/
609+
var patientWithPaidOffBalance = JsonConvert.DeserializeObject<JObject>(client.Get(new RestRequest("patients/{id}").AddParameter("id", patients["patients"][0]["id"], ParameterType.UrlSegment)).Content);
610+
Console.WriteLine("Patient id " + patientWithPaidOffBalance["patient"]["id"] + " balance is " + patientWithPaidOffBalance["patient"]["balance_cents"]);
611+
}
612+
}
613+
}
614+
```
615+
401616
## FAQs
402617
Please don't hesitate to ask questions via our email, Slack or GitHub Issues. We'll update this section with common questions as we work to flesh out our documentation.
403618

0 commit comments

Comments
 (0)