NAV

Introduction

We help you to calculate and report your business metrics. For us to do that accurately, you have to keep Probe updated about all the changes that may affect your revenue.

Should you face any difficulties while using our API or find that something is unclear - we would really appriciate your feedback. Just email Alex at support@getprobe.io.

Authorization

Authorization to Probe API is handled by supplying each API request with an HTTP Authorization: Bearer <API TOKEN> header.

Please write to Alex at support@getprobe.io to obtain your Probe API token.

Pagination

For APIs that return a list of objects you have to use pagination to get all objects.

We use cursor-based pagination. There is a special parameter, next that you will receive in a response. Pass the value to a subsequent request as a query parameter to access next page of JSON objects. Repeat this process until next is null which indicates you hit the last page.

Currently the number of objects returned for each request is 100 and it is not possible to change it.

Response format for list API

{
  "items": [
    {
      "id": "sub_1",
      # ...
    },
    {
      "id": "sub_2",
      # ...
    },
  ]
  "next": "eyJ2ZXJzaW9uIjoxLCJkYXRhIjp7Imxhc3RfaWQiOjIxfX0"
}
Attribute Description
items List of JSON objects you are paginating through
next String representing pagination token you should pass to next request to iterate further. Last page will have "next": null

Getting Started

We use the Subscription model to track usage of your product for each customer. Each time something changes - the customer starts paying you or stops having access to your product - you have to update Probe with this information. We will keep a full history of changes for each Subscription. You can get access to this history via the API.

Below is an example of a typical Subscription’s lifecycle and updates that needed to be made to Probe.

Create trial subscription

Creating a new subscription when the customer signs up for a Trial.

curl -d \
  '{
    "customer_id": "abc",
    "id": "sub_1",
    "started_at": "2019-09-06T13:00:00",
    "items": [{
      "product_key":"starter",
      "type":"trial",
      "trial_started_at":"2019-09-06T13:00:00",
      "trial_ended_at":"2019-09-13T13:00:00"
    }]
  }' \
  -H 'Authorization: Bearer API_TOKEN' \
  -H 'Content-Type: application/json' \
  -X PUT https://api.getprobe.io/v4/subscriptions/upsert

Returns

{
   "created_at": "2019-10-23T13:29:48Z",
   "customer_id": "abc",
   "id": "sub_1",
   "started_at": "2019-09-06T13:00:00Z",
   "ended_at": null,
   "items": [
      {
         "type": "trial",
         "product_key": "starter",
         "trial_started_at": "2019-09-06T13:00:00Z",
         "trial_ended_at": "2019-09-13T13:00:00Z"
      }
   ]
}

When a customer creates a new Trial account in your system, you would usually create a subscription in Probe.

The new subscription will be created with id = sub_1. We will use this id for reporting all future changes that may happen for this subscription. We rely on the id to understand if a new subscription should be created or an existing one should be updated. I. e. if we don’t find a subscription with the provided id we will create a new one. If you do not provide id we will generate it for you.

Create recurring subscription

Notice type=recurring to report a recurring customer

curl -d \
  '{
    "currency": "usd",
    "id": "sub_1",
    "started_at": "2019-09-11T13:00:00",
    "monthly_amount": "100.45",
    "items": [{
      "product_key":"starter",
      "type":"recurring"
    }]
  }' \
  -H 'Authorization: Bearer API_TOKEN' \
  -H 'Content-Type: application/json' \
  -X PUT https://api.getprobe.io/v4/subscriptions/upsert

Returns

{
  "created_at": "2019-10-23T14:06:33Z",
  "currency": "usd",
  "customer_id": "abc",
  "id": "sub_1",
  "started_at": "2019-09-11T13:00:00Z",
  "ended_at": null,
  "monthly_amount": "100.45",
  "items":[
     {
       "type": "recurring",
       "product_key": "starter",
       "trial_started_at": "2019-09-06T13:00:00Z",
       "trial_ended_at": "2019-09-13T13:00:00Z"
     }
  ]
}

When the customer starts paying you, you need to update the subscription with a monthly amount that will be counted into your revenue.

In the example on the right, the customer starts paying for a product called starter. Notice we post a new item with type=recurring under the subscription items, providing the currency used and a monthly_amount, as well as setting started_at to a timestamp indicating when the state of the subscription has changed.

Update subscription amount

There is no need to provide items because they did not change

curl -d \
  '{
    "id": "sub_1",
    "started_at": "2019-10-10T13:00:00",
    "monthly_amount": "250.50"
  }' \
  -H 'Authorization: Bearer API_TOKEN' \
  -H 'Content-Type: application/json' \
  -X PUT https://api.getprobe.io/v4/subscriptions/upsert

Returns

{
  "created_at": "2019-10-23T14:25:02Z",
  "currency": "usd",
  "customer_id": "abc",
  "id": "sub_1",
  "started_at": "2019-10-10T13:00:00Z",
  "ended_at": null,
  "monthly_amount": "250.5",
  "items":[
    {
      "type": "recurring",
      "product_key": "starter",
      "trial_started_at": "2019-09-06T13:00:00Z",
      "trial_ended_at": "2019-09-13T13:00:00Z"
    }
  ]
}

When a customer starts to pay you more or less due to an increase/decrease in their product usage, you need to update the subscription's monthly_amount.

In this example the customer starts to pay you 250.50 USD beginning on the 10th of October. Notice, that we do not provide subscription items here. That is because it is not mandatory to provide values for fields that have not changed.

Add new product

curl -d \
  '{
    "id": "sub_1",
    "started_at": "2019-10-30T13:00:00",
    "monthly_amount": "290.99",
    "items":[
      {"product_key":"starter"},
      {"product_key":"expansion-pack", "type":"recurring"}
    ]
  }' \
  -H 'Authorization: Bearer API_TOKEN' \
  -H 'Content-Type: application/json' \
  -X PUT https://api.getprobe.io/v4/subscriptions/upsert

Returns

{
  "created_at": "2019-10-24T14:16:56Z",
  "currency": "usd",
  "customer_id": "abc",
  "id": "sub_1",
  "started_at": "2019-10-30T13:00:00Z",
  "ended_at": null,
  "monthly_amount": "290.99",
  "items":[
    {
      "type": "trial",
      "product_key": "starter",
      "trial_started_at": "2019-09-06T13:00:00Z",
      "trial_ended_at": "2019-09-13T13:00:00Z"
    },
    {
      "type": "recurring",
      "product_key": "expansion-pack",
      "trial_started_at":null,
      "trial_ended_at":null
    }
  ]
}

In the example above the customer has bought a new product - expansion-pack, we also updated the monthly_amount. When you want to update subscription items you always have to send all the products that are currently active for the customer. In the example above if you didn't provide the starter item, it would be removed from the subscription. The customer would be left with only the expansion-pack product.

You can remove or add products for the customer in a similar fashion.

Cancel subscription

curl -d \
  '{
    "id": "sub_1",
    "started_at": "2019-12-30T13:00:00",
    "ended_at": "2019-12-30T13:00:00"
  }' \
  -H 'Authorization: Bearer API_TOKEN' \
  -H 'Content-Type: application/json' \
  -X PUT https://api.getprobe.io/v4/subscriptions/upsert

Returns

{
  "created_at": "2019-10-23T14:34:31Z",
  "currency": "usd",
  "customer_id": "abc",
  "id": "sub_1",
  "started_at": "2019-12-30T13:00:00Z",
  "ended_at": "2019-12-30T13:00:00Z",
  "monthly_amount": "290.99",
  "items":[
    {
      "type": "trial",
      "product_key": "starter",
      "trial_started_at": "2019-09-06T13:00:00Z",
      "trial_ended_at": "2019-09-13T13:00:00Z"
    },
    {
      "type": "recurring",
      "product_key": "expansion-pack",
      "trial_started_at":null,
      "trial_ended_at":null
    }
  ]
}

When the customer is not using your product any longer, you have to let us know by setting the ended_at field on the subscription.

In this example, the subscription will end on the 30th of December and won't be counted into your MRR from that moment on. Notice that both starter and expansion-pack will be ended. If you want to remove only one of them from the subscription, you can do that by updating the subscription items section as described in Add new product.

Subscriptions

Subscription object

This is the JSON representation of the subscription object

{
   "created_at": "2019-10-22T12:08:05Z",
   "currency": "usd",
   "customer_id": "customer_1",
   "id": "sub_1",
   "started_at": "2019-10-22T11:07:24Z",
   "ended_at": "2019-11-22T11:07:24Z",
   "monthly_amount": "55.5",
   "items":[
      {
         "type": "recurring",
         "product_key": "starter"
      }
   ]
}

The subscription object represents how much each customer is contributing to your MRR.

Attributes

Attribute Description
created_at String in ISO-8601 date format. DateTime when the subscription was created within Probe.
currency String. ISO currency code in which you receive the payment. Ex. "usd"
customer_id String. Unique identifier of the customer within your system.
ended_at String in ISO-8601 date format. DateTime when the subscription has or will end.
id Unique identifier of the subscription object.
started_at String in ISO-8601 date format. Date when the current subscription change became active for the customer.
monthly_amount A string with decimals separated by dot. Ex. "45.12". The monthly amount counted into your MRR.
items Array. List of subscription item objects.

Subscription Item object

Attribute Description
type Possible values: trial, freemium, recurring, one_time, metered
Use trial if the customer is trialing a given product. Use freemium if you have a freemium model for a given product. Use recurring if the customer is paying for a product. Use one_time to note a one-time payment that doesn't contribute to SaaS metrics. Use metered to note a recurring payment but with usage-based pricing.
product_key String containing only letters and numbers. Key of the product the customer subscribed for.
trial_started_at String in ISO-8601 date format. If a customer is trialing a product, the date when the trial has started.
trial_ended_at String in ISO-8601 date format. If a customer is trialing product, the date when the trial will end. This can be null in case you are giving freemium access to your product.

Upserting new subscription

Each time the state of a subscription changes within your system, or a new subscription is created, you have to report this state change to Probe. In this way, Probe is able to accurately report your MRR.

You can use the Upsert API to report any such state change.

HTTP Request

PUT https://api.getprobe.io/v4/subscriptions/upsert

Query params

Param Description
currency required
String. ISO currency code in which you receive the payment. E.g. "usd".
The behavior depends on the monthly_amount param. You have to provide a currency if you are providing a monthly_amount.
customer_id required
Unique identifier of the customer within your system. This param is required when you are reporting a new subscription for a given customer.
ended_at optional
String in ISO-8601 date format. DateTime when the subscription has or will end.
id optional
Unique string identifier of the subscription object provided by you or generated by Probe if none was supplied. We suggest that you provide this param and that its value correspond to the id you use in your system for this subscription.
started_at required
String in ISO-8601 date format. Date when the current subscription change became active for the customer.
monthly_amount required
A string with decimals separated by dot. Ex. "45.12". The monthly amount counted into your MRR. The behavior depends on the type of subscription item you creating. If there are paying items, monthly_amount is required.
items required
List of subscription item objects (see below). At least one item must be present when reporting a new subscription for the first time.

Subscription Item object

Attribute Description
type required
Possible values: trial, freemium, recurring, one_time, metered
Use trial if the customer is trialing a giving product. Use freemium if you have a freemium model for a given product. Use recurring if the customer is paying for a product. Use one_time to note a one-time payment that doesn't contribute to SaaS metrics. This param is required when reporting an item for the first time. At later stages you can just use product_key to report that the item is still part of the subscription. Use metered to note a recurring payment but with usage-based pricing.
product_key required
String containing only letters and numbers. Key of the product the customer subscribed for.
trial_started_at required
String in ISO-8601 date format. This param is required when creating an item with type=trial or type=freemium. The timestamp when customer created trial or freemium account within your system.
trial_ended_at required
String in ISO-8601 date format. If a customer is trialing a product, the date when the trial will end. Required when type=trial. This can be null in case you are giving freemium access to your product.

Returns

Returns the new state of the Subscription object.

Listing subscriptions

curl \
  -H 'Authorization: Bearer API_TOKEN' \
  -H 'Content-Type: application/json' \
  -X GET https://api.getprobe.io/v4/subscriptions

Returns

{
  "items":[
    {
      "created_at": "2019-10-23T14:34:31Z",
      "currency": "usd",
      "customer_id": "abc",
      "id": "sub_1",
      "started_at": "2019-12-30T13:00:00Z",
      "ended_at": "2019-12-30T13:00:00Z",
      "monthly_amount": "290.99",
      "items":[
        {
          "type": "trial",
          "product_key": "starter",
          "trial_started_at": "2019-09-06T13:00:00Z",
          "trial_ended_at": "2019-09-13T13:00:00Z"
        },
        {
          "type": "recurring",
          "product_key": "expansion-pack",
          "trial_started_at":null,
          "trial_ended_at":null
        }
      ]
    }
  ],
  "next": "eyJ2ZXJzaW9uIjoxLCJkYXRhIjp7Imxhc3RfaWQiOjIxfX0"
}

Use this endpoint to list all subscriptions present in the system. It returns the latest state of each subscription.

This endpoint is paginated.

HTTP Request

GET https://api.getprobe.io/v4/subscriptions

Query params

Param Description
next optional
String representing pagination token.

Response body

Attribute Description
items List of subscriptions. See Subscription Object.
next String with pagination token to attach to next request. If null, it's the last page.

Returns

Latest state of Subscription objects.

Destroying subscription

curl \
  -H 'Authorization: Bearer API_TOKEN' \
  -H 'Content-Type: application/json' \
  -X DELETE https://api.getprobe.io/v4/subscriptions/:id

Returns

204 No Content

You can remove all data for a specific subscription by destroying it, which will completely remove the subscription from our system. Later on you can add the same subscription if you wish.

HTTP Request

DELETE https://api.getprobe.io/v4/subscriptions/:id

Query params

Param Description
id required
ID of the subscription to be destroyed.

Returns

This API returns no content.

Subscription histories

Subscription history object

This is the JSON representation of the subscription history object

{
  "id": "subh_4bRliAkezdnE",
  "user_id": "user_QBu0pPpK1HbI",
  "customer_id": "cus_IyJWtuDx3Bll",
  "subscription_id": "sub_I7DkuettCSQnzb",
  "started_at": "2021-03-30T07:00:00.000Z",
  "ended_at": "2021-09-30T07:00:00.000Z",
  "duration_in_months": 6,
  "original_total_value": "30000.0",
  "original_monthly_amount": "5000.0",
  "original_currency": "usd",
  "total_value": "30000.0",
  "monthly_amount": "5000.0",
  "currency": "usd",
  "items": [
    {
      "type": "recurring",
      "product_key": "BasicPlan"
    }
  ],
  "created_at": "2021-03-30T13:26:00.000Z"
}

Subscription history represents a payment related to a subscription of a customer.

Attributes

Attribute Description
id String. Unique identifier of the subscription history object.
user_id String. ID of the user object who created this subscription history.
customer_id String. ID of the customer object that this history refers to.
subscription_id String. ID of the subscription object that this payment refers to.
started_at String in ISO-8601 date format. DateTime when the payment started.
ended_at String in ISO-8601 date format. DateTime when the payment ended.
duration_in_months Number. Represents the duration in months of the payment.
total_value String. Total amount paid, that is duration_in_months * monthly_amount. Represented in your account currency.
monthly_amount String. Monthly amount for this payment. Represented in your account currency.
currency String. ISO code of your account currency.
original_total_value String. Total amount paid, that is duration_in_months * monthly_amount.
original_monthly_amount String. Monthly amount for this payment.
original_currency String. ISO code of currency.
items Array. List of items related to that payment.
created_at String in ISO-8601 date format. DateTime when this object was created within Probe.

Subscription history item object

Param Description
type String. One of recurring (recurring revenue), metered, (recurring revenue for usage-based products), or one_time for one-time payments
product_key String. Name of the product.

Both recurring and metered types are counted towards metrics like MRR, Churn, Contraction etc.

The one_time type represents a one-time payment that is counted towards your Revenue / Cash flow. It does not contribute to SaaS-related metrics.

Currently we don't support more than one item per history. If you have such case, please split each item into separate subscription history.

Upserting a subscription history

This API creates or updates an existing subscription history by id. When the subscription history is created, the customer and subscription related to it are also created based on customer_id and subscription_id attribute. If the subscription_id attribute is not provided when creating a history, it will be auto-generated.

When updating an existing subscription history the relation to customer or subscription isn't changed. Moreover, if you provide customer_id or subscription_id attributes and the history already exists, we will check that the attributes match the existing state and return error if they don't.

curl -d \
  '{
    "subscription_id": "acme-deal-2021",
    "customer_id": "acme",
    "currency": "PLN",
    "monthly_amount": "95.90",
    "started_at": "2021-12-05T15:00:00Z",
    "ended_at": "2022-12-05T15:00:00Z",
    "items": [{"product_key": "basic", "type": "recurring"}]
  }' \
  -H 'Authorization: Bearer API_TOKEN' \
  -H 'Content-Type: application/json' \
  -X PUT https://api.getprobe.io/v4/subscriptions/history/upsert/invoice_12_2021

HTTP Request

POST https://api.getprobe.io/v4/subscriptions/history/upsert/:id

Params

Param Description
id required
ID of the subscription history.
customer_id required
String. ID of the customer object that this history refers to.
subscription_id String. ID of the subscription object that this history refers to. Auto-generated if not provided.
started_at required
String in ISO-8601 date format. DateTime when the subscription history started.
ended_at required
String in ISO-8601 date format. DateTime when the subscription history ended.
monthly_amount required
String. Monthly amount of this payment in original currency.
currency required
String. ISO code of payment's currency.

Response body

See Subscription History Object.

Returns

Subscription history object.

Returns

{
  "id": "subh_4bRliAkezdnE",
  "user_id": "user_QBu0pPpK1HbI",
  "customer_id": "cus_IyJWtuDx3Bll",
  "subscription_id": "sub_I7DkuettCSQnzb",
  "started_at": "2021-03-30T07:00:00.000Z",
  "ended_at": "2021-09-30T07:00:00.000Z",
  "duration_in_months": 6,
  "original_total_value": "30000.0",
  "original_monthly_amount": "5000.0",
  "original_currency": "usd",
  "total_value": "30000.0",
  "monthly_amount": "5000.0",
  "currency": "usd",
  "items": [
    {
      "type": "recurring",
      "product_key": "BasicPlan"
    }
  ],
  "created_at": "2021-03-30T13:26:00.000Z"
}

Customers

Customer object

This is the JSON representation of the customer object

{
  "id": "my-id-42",
  "segments": [
    {
      "name": "industry",
      "value": "software"
    }
  ],
  "added_at": "2019-11-22T11:07:24Z",
  "updated_at": "2019-11-22T11:07:24Z"
}

The customer object represents your customer. It is related to your internal system by id attribute and can have segments attached to it.

Attributes

Attribute Description
id String. Unique identifier of the customer within your system.
segments Array. List of segment objects.
added_at String in ISO-8601 date format. DateTime when the subscription was created within Probe.
updated_at String in ISO-8601 date format. Date when the current subscription change became active for the customer.

Segment object

Param Description
name String. Name of the segment.
value String. Value of the segment.

Getting customer

Show current information about customer, including segments they are in.

curl \
  -H 'Authorization: Bearer API_TOKEN' \
  -H 'Content-Type: application/json' \
  -X GET https://api.getprobe.io/v4/customers/my-id-42

HTTP Request

GET https://api.getprobe.io/v4/customers/:id

Query params

Param Description
id required
ID of the customer within your system.

Response body

See Customer Object.

Returns

Customer object.

Returns

{
  "id": "my-id-42",
  "segments": [
    {
      "name": "industry",
      "value": "software"
    }
  ],
  "added_at": "2020-05-21T15:07:15Z",
  "updated_at": "2020-05-21T15:07:15Z"
}

Updating customer segments

Segments are simple key-value pairs which can be used to segment your metrics. Each segment has a name which is a String, and a value which is also a String.

To add or overwrite a segment value on a customer simply include it in segments array with its name and value. Notice that other existing segments remain unchanged by this operation.

To remove an existing segment include a name of the segment with a value set to null.

Segments have a unique name so including two segments with the same name in the segments array will result in an error.

# adding (or updating) "industry" = "hardware" to the existing segments
curl -d \
  '{
     "segments": [
       {
         "name": "industry",
         "value": "hardware"
       }
     ]
  }' \
  -H 'Authorization: Bearer API_TOKEN' \
  -H 'Content-Type: application/json' \
  -X PUT https://api.getprobe.io/v4/customers/my-id-42
# removing an existing "industry" segment while keeping other
# segments unchanged
curl -d \
  '{
     "segments": [
       {
         "name": "industry",
         "value": null
       }
     ]
  }' \
  -H 'Authorization: Bearer API_TOKEN' \
  -H 'Content-Type: application/json' \
  -X PUT https://api.getprobe.io/v4/customers/my-id-42

HTTP Request

PUT https://api.getprobe.io/v4/customers/:id

Query params

Param Description
id required
ID of the customer within your system.
segments Array. List of segment objects.

Segment object

Param Description
name required
String. Name of the segment.
value required
String or null. Value of the segment or null to remove segment.

Response body

See Customer Object.

Returns

{
  "id": "my-id-42",
  "segments": [
    {
      "name": "industry",
      "value": "hardware"
    }
  ],
  "added_at": "2020-05-21T15:07:15Z",
  "updated_at": "2020-05-21T15:08:03Z"
}

Errors

Probe uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong.
404 Not Found -- The specified subscription could not be found.
500 Internal Server Error -- We had a problem with our server. We are working to fix it but feel free to get in touch with more details.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.

Help

If you encounter any difficulties just email us at support@getprobe.io.