January Developer Docs

Download OpenAPI specification:Download

API

About

The January API is a set of programmatic endpoints that can be used to interact with January data. This API is documented in OpenAPI format.

Authentication

January will generate an API token to use with all of your requests. You can attach the token in the header with the following key value:

Authorization: Bearer <API_TOKEN >

apiKey

Prefix the value with "Bearer" to indicate the custom authorization type: Bearer <API_TOKEN>

Security Scheme Type: API Key
Header parameter name: Authorization

Rate Limit

All API requests have a rate limit of 100 / minute. Please contact us if this is insufficient for your needs.

Pagination

Endpoints that use pagination will accept page and limit arguments as query parameters. A max of 1000 results per page will be returned. page will default to 1 unless a value is given and limit will default to 1000.

When reading paginated responses from the API, the follow response headers will be sent:

  • X-Page: The current page
  • X-Per-Page: The current limit
  • X-Total-Count: The total number of pages available

Dates

All dates should be in ISO8601 format, e.g. '2020-08-13'.

Currency

All currency fields should be provided as integers representing the number of cents. In other words, the dollar amount $1.99 should be sent as 199, not as 1.99 or as "$1.99".

Responses

Every response will contain a X-January-API-Request-ID value, unique to a response.

Success response structure

Successful responses are indicated with a 200-series HTTP code and a JSON-based payload. The data field in JSON responses will contain the specific objects associated with the leveraged resource.

Error response structure

Error responses are indicated with a non-200-series HTTP code and sometimes a JSON-based payload. We cannot guarantee that all error responses will contain the same response format or a consistent repsonse format, we recommend that the HTTP code's core meaning to take precedence.

API stability

In general, January will only make backwards-compatible changes to our APIs. For example, we might:

  • Make new properties available on JSON objects
  • Allow new parameters as inputs
  • Make changes specified as valid by this documentation, even if the behavior is new (for example, we might begin returning null for a property even if we never returned null for that property before as long as we documented the field as nullable)

If we need to make a breaking change, we will introduce a new API endpoint. For example, the following would be breaking changes:

  • Changing the shape of JSON responses other than adding new properties
  • Adding a new value to an enum, or changing the semantics of an existing value
  • Imposing additional requirements on API inputs

There are exceptions to this stability promise. Specifically, new APIs will be marked "Beta" for a while, and are not subject to this policy. This is to allow us to quickly iterate on APIs so they can better serve clients' needs. Clients making use of APIs marked "Beta" should expect to work directly with us to adjust to changes we make to the API as it evolves.

We will announce API deprecations in advance and provide a timeline for transitioning to replacements.

Webhooks

About

Webhooks allow you to opt into receiving real-time events about the accounts you've placed with January. These events are sent via HTTPS to your backend system. Some examples of real-time events include being alerted when a borrower has made a payment, or when an account has been fully paid off.

Note: Webhook events are only available for pre-chargeoff accounts.

Authentication

To validate that a webhook was sent by January, every incoming request is signed with a signature stored under the HTTP Header x-signature.

Signature

To extract the signature, please hash the request body using HMAC SHA-256, with your webhook key as the shared secret (see "Retrieving Your Webhook Key" below).

Validating the Signature

The signature you generate above should be equivalent to the signature we pass through the HTTP Header x-signature. If not, the request may be from another source.

Retrieving Your Webhook Key

  • Contact api@january.com to request your private webhook key - please do NOT share this key outside your organization.
  • If your webhook key is accidentally exposed to the public, please contact api@january.com to rotate your key.

Subscribing to Webhooks

To subscribe to a webhook, please contact api@january.com outlining:

  • Webhook Name: which webhook you want to subscribe to (e.g. payment_plan_created). See "Webhook Events" section below for a list of webhooks.
  • Webhook URL: the endpoint URL you want the webhook request to be sent to (e.g. https://www.client-name.com/events/payment-plan/create).
    • We will be making HTTP POST requests to this endpoint. To see a detailed request body schema, refer to the Webhooks documentation section below.

Retries

  • We will retry each webhook event up to 10 times if we receive a non 2XX response from your webhook subscription URL.
  • Please respond to the request with a 200 to confirm successful receipt of the request.

Webhook Events

The below is a list of all the webhook events you can subscribe to, followed by a description of what information will be shared:

  1. payment_plan_created - A payment plan was created for an account.
  2. payment_plan_updated - A payment plan was updated for an account.
  3. payment_plan_deleted - A payment plan was deleted for an account.
  4. payment_received - A payment was successfully received and applied to an account.
  5. payment_returned - A payment was returned (i.e. refunded or charged back).
  6. email_sent - January (as the client) sent an email to a borrower.
  7. email_received - January (as the client) received an email from a borrower.
  8. inbound_phone - January (as the client) received an incoming phone call from a borrower.
  9. outbound_phone - January (as the client) made an outgoing phone call to a borrower.
  10. account_status_update - A borrower's account status has changed, e.g. from placed to resolved.

Sample Webhook Handler

This below snippet is an example handler for webhook events (in Python).

def _is_valid_january_signature():
    def wrapper(event_handler):
        def wrapped_event_handler(*args):
            webhook_signature = request.headers["x-signature"]
            body = request.get_data()
            secret_key = <your webhook key (ideally retrieved from some kind of secure secret storage)>
            derived_signature = hmac.new(
                bytes(
                    secret_key,
                    "utf-8",
                ),
                body,
                hashlib.sha256,
            ).hexdigest()
            if hmac.compare_digest(
                bytes(derived_signature, "utf-8"), bytes(webhook_signature, "utf-8")
            ):
                return event_handler(*args)
            else:
                abort(403, "Invalid Signature")

        wrapped_event_handler.__name__ = event_handler.__name__
        return wrapped_event_handler

    return wrapper


@api.route("/january_events/transactions", methods=("POST",))
@_is_valid_january_signature()
def handle_webhook():
    logger.info(
        "Webhook received",
        {"json": request.json, "headers": request.headers},
    )
    return jsonify({"foo": "bar"}), 200

Troubleshooting and support

For support and feedback please email api@january.com, we'd love to hear from you.

health check

Connection and health status of January API

Check application availability

(Stability: production)

Authorizations:
apiKey

Responses

debt

Retrieve and update debts

Retrieve list of debts

(Stability: beta)

Authorizations:
apiKey
query Parameters
page
integer

Page of results

limit
integer

Maximum number of results returned

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Update an existing debt

Update a debt or multiple debt balances (Stability: beta)

Authorizations:
apiKey
Request Body schema: application/json
Array
debtID
required
string

Client specific identifier for a debt. This is most likely an account number.

required
Array of objects

Responses

Request samples

Content type
application/json
[
  • {
    }
]

Response samples

Content type
application/json
{
  • "errors": [
    ]
}

Find debt by id

(Stability: beta)

Authorizations:
apiKey
path Parameters
debtID
required
string

Client specific identifier for a debt

Responses

Response samples

Content type
application/json
{
  • "debt": {
    }
}

transaction

Access debtor transactions

Retrieve list of transactions

(Stability: beta)

Authorizations:
apiKey
query Parameters
startDate
date
endDate
date
debtID
string

Client specific identifier for a debt

transactionType
string
Enum: "adjustment" "payment"
page
integer

Page of results

limit
integer

Maximum number of results returned

Responses

Response samples

Content type
application/json
[
  • {
    }
]

placement

Create debts

Create new debts async

Asynchronously create up to 10,000 new debts at a time. (Stability: beta)

Authorizations:
apiKey
Request Body schema: application/json
One of
Array
required
object ($defs-debt)
required
object (debtor)
object (debtor)

Responses

Request samples

Content type
application/json
Example
[ ]

Response samples

Content type
application/json
{
  • "placementID": "string",
  • "status": "pending"
}

Retrieve placement status

Retrieve status of placement initiated by post /v2/placements. (Stability: beta)

Authorizations:
apiKey
path Parameters
placementID
required
string

Responses

Response samples

Content type
application/json
{
  • "placementID": "string",
  • "status": "pending",
  • "totals": {
    },
  • "successes": [
    ],
  • "failures": [
    ]
}

recall

Recall debts

Recall a debt

(Stability: production)

Authorizations:
apiKey
Request Body schema: application/json
Array
debtID
required
string

Client specific identifier for a debt. This is most likely an account number.

type
required
string
Enum: "compliance" "swap"

Type of recall request

reason
required
string
Enum: "bankrupt" "deceased" "litigious-consumer" "active-military" "incarcerated" "other"

Reason for recall request

note
string

Further detail on the recall request

Responses

Request samples

Content type
application/json
[
  • {
    }
]

Response samples

Content type
application/json
{
  • "successes": [
    ],
  • "failures": [
    ]
}

communications

Track communications between January and borrowers

emailSent Webhook

Request Body schema: application/json

Receieve a real-time request when January, as the client, sends an email to a borrower

debtID
string

Client specific identifier for a debt

eventTime
string <date-time>

When the event took place

eventType
string
Value: "emailSent"
commID
string <uuid>

January identifier for this communication

emailAddress
string <email>

The email address January sent an email to

subject
string

The subject line of the email

Responses

Request samples

Content type
application/json
{
  • "debtID": "string",
  • "eventTime": "2023-03-22T19:39:47.954736+00:00",
  • "eventType": "emailSent",
  • "commID": "5636959f-19a1-4e26-87c4-27ee0779678b",
  • "emailAddress": "user@example.com",
  • "subject": "string"
}

emailReceived Webhook

Request Body schema: application/json

Receieve a real-time request when January, as the client, receives an email from a borrower

debtID
string

Client specific identifier for a debt

eventTime
string <date-time>

When the event took place

eventType
string
Value: "emailReceived"
commID
string <uuid>

January identifier for this communication

emailAddress
string <email>

The email address January received an email from

subject
string

The subject line of the email

Responses

Request samples

Content type
application/json
{
  • "debtID": "string",
  • "eventTime": "2023-03-22T19:39:47.954736+00:00",
  • "eventType": "emailReceived",
  • "commID": "5636959f-19a1-4e26-87c4-27ee0779678b",
  • "emailAddress": "user@example.com",
  • "subject": "string"
}

outboundPhone Webhook

Request Body schema: application/json

Receieve a real-time request when January, as the client, makes an outbound phone call to a borrower at their request

debtID
string

Client specific identifier for a debt

eventTime
string <date-time>

When the event took place

eventType
string
Value: "outboundPhone"
commID
string <uuid>

January identifier for this communication

phoneNumber
string <phone>

Responses

Request samples

Content type
application/json
{
  • "debtID": "string",
  • "eventTime": "2023-03-22T19:39:47.954736+00:00",
  • "eventType": "outboundPhone",
  • "commID": "5636959f-19a1-4e26-87c4-27ee0779678b",
  • "phoneNumber": "string"
}

inboundPhone Webhook

Request Body schema: application/json

Receieve a real-time request when January, as the client, receives a phone call from a borrower

debtID
string

Client specific identifier for a debt

eventTime
string <date-time>

When the event took place

eventType
string
Value: "inboundPhone"
commID
string <uuid>

January identifier for this communication

phoneNumber
string <phone>

Responses

Request samples

Content type
application/json
{
  • "debtID": "string",
  • "eventTime": "2023-03-22T19:39:47.954736+00:00",
  • "eventType": "inboundPhone",
  • "commID": "5636959f-19a1-4e26-87c4-27ee0779678b",
  • "phoneNumber": "string"
}

payment plan

Monitor payment plan creation, update, or deletion

paymentPlanCreated Webhook

Request Body schema: application/json

Receieve a real-time request when a payment plan was created for an account.

Note: January prevents the creation of a payment plan within 7 days of an account's charge-off date. Borrowers are still able to make payments in full towards their overdue balance.

debtID
string

Client specific identifier for a debt

eventTime
string <date-time>

When the event took place

eventType
string
Value: "paymentPlanCreated"
planID
string <uuid>

January identifier for the payment plan

cadence
string
Enum: "weekly" "every-two-weeks" "monthly" "first-and-fifteenth"

Cadence at which this payment plan charges a borrower

installmentAmount
integer

Installment amount (in cents) to be charged at the cadence the borrower specifies

coveredAmount
integer

Total balance (in cents) to be covered under this payment plan

firstPaymentDate
string <date>

The day the payment plan starts and when we first charge a borrower

Responses

Request samples

Content type
application/json
{
  • "debtID": "string",
  • "eventTime": "2023-03-22T19:39:47.954736+00:00",
  • "eventType": "paymentPlanCreated",
  • "planID": "b3e38790-d1c0-4afb-b75c-aa44e99a6877",
  • "cadence": "every-two-weeks",
  • "installmentAmount": 15050,
  • "coveredAmount": 45150,
  • "firstPaymentDate": "2023-03-30"
}

paymentPlanUpdated Webhook

Request Body schema: application/json

Receieve a real-time request when a payment plan was updated

debtID
string

Client specific identifier for a debt

eventTime
string <date-time>

When the event took place

eventType
string
Value: "paymentPlanUpdated"
planID
string <uuid>

January identifier for the payment plan

cadence
string
Enum: "weekly" "every-two-weeks" "monthly" "first-and-fifteenth"

Cadence at which this payment plan charges a borrower

installmentAmount
integer

Installment amount (in cents) to be charged at the cadence the borrower specifies

coveredAmount
integer

Total balance (in cents) to be covered under this payment plan

firstPaymentDate
string <date>

The day the payment plan starts and when we first charge a borrower

Responses

Request samples

Content type
application/json
{
  • "debtID": "string",
  • "eventTime": "2023-03-22T19:39:47.954736+00:00",
  • "eventType": "paymentPlanUpdated",
  • "planID": "b3e38790-d1c0-4afb-b75c-aa44e99a6877",
  • "cadence": "weekly",
  • "installmentAmount": 30100,
  • "coveredAmount": 45150,
  • "firstPaymentDate": "2023-03-30"
}

paymentPlanDeleted Webhook

Request Body schema: application/json

Receieve a real-time request when a payment plan was deleted

debtID
string

Client specific identifier for a debt

eventTime
string <date-time>

When the event took place

eventType
string
Value: "paymentPlanDeleted"
planID
string <uuid>

January identifier for the payment plan

Responses

Request samples

Content type
application/json
{
  • "debtID": "string",
  • "eventTime": "2023-03-22T19:39:47.954736+00:00",
  • "eventType": "paymentPlanDeleted",
  • "planID": "b3e38790-d1c0-4afb-b75c-aa44e99a6877"
}

payment

Monitor payments made by borrowers

paymentReceived Webhook

Request Body schema: application/json

Receieve a real-time request when a payment is successfully received and applied to an account

debtID
string

Client identifier for the debt this event pertains to

eventTime
string <date-time>

When the event took place

eventType
string
Value: "paymentReceived"
paymentID
string <uuid>

January identifier for the payment

amount
integer

Payment amount in cents

paymentMethod
string
Enum: "ach" "check" "debit" "plaid"

Responses

Request samples

Content type
application/json
{
  • "debtID": "string",
  • "eventTime": "2023-03-22T19:39:47.954736+00:00",
  • "eventType": "paymentReceived",
  • "paymentID": "471b4c61-4e6a-414a-9a08-2528498de3f3",
  • "amount": 25050,
  • "paymentMethod": "ach"
}

paymentReturned Webhook

Request Body schema: application/json

Receieve a real-time request when a payment is returned (i.e. refunded or charged back)

debtID
string

Client specific identifier for a debt

eventTime
string <date-time>

When the event took place

eventType
string
Value: "paymentReturned"
returnedPaymentID
string <uuid>

References the paymentID of the payment that was returned

amount
integer <= 0

A negative integer amount returned in cents

reason
string
Enum: "chargeback" "refund"

Describes whether the transaction was charged back or refunded

Responses

Request samples

Content type
application/json
{
  • "debtID": "string",
  • "eventTime": "2023-03-22T19:39:47.954736+00:00",
  • "eventType": "paymentReturned",
  • "returnedPaymentID": "cec96196-7439-4643-9a38-b43dc8b35244",
  • "amount": -25050,
  • "reason": "chargeback"
}

account status

Monitor the status of accounts. Possible statuses include:

  • placed: January is working to collect on this account.
  • ceased: January is no longer working to collect on this account. Possible reasons include:
    • Bankruptcy Notice
    • Deceased Notice
  • canceled: January is no longer working to collect on this account because it was recalled by the client.
  • resolved: January is no longer working to collect on this account because it has been paid in full.
  • charged-off: January is no longer working to collect on this account because it is charged-off.

accountStatusUpdate Webhook

Request Body schema: application/json

Receieve a real-time request when the status of an account changes

debtID
string

Client specific identifier for a debt. This is most likely an account number.

eventTime
string <date-time>

When the event took place

eventType
string
Value: "accountStatusUpdate"
previousStatus
string
Enum: "placed" "resolved" "ceased" "canceled" "charged-off"
currentStatus
string
Enum: "placed" "resolved" "ceased" "canceled" "charged-off"

Responses

Request samples

Content type
application/json
{
  • "debtID": "string",
  • "eventTime": "2023-03-22T19:39:47.954736+00:00",
  • "eventType": "accountStatusUpdate",
  • "previousStatus": "placed",
  • "currentStatus": "placed"
}