NAV

shell ruby

Introduction

API Endpoint

https://api.firstofficer.io

Current version: V2 (BETA, under development)

This API gives you a REST-based access to your SaaS metrics. You need a FirstOfficer.io subscription to use the API.

JSON is returned by all API responses, including errors.

Please note that the API is currently in beta and contents may change. V2 will be the first publicly available version and all non-backwards compatible changes will be made to a new API version.

At the moment there are not query limits at place, so please use common sense when retrieving data. FirstOfficer updates your data once per hour.

Authentication

To authenticate, add your API key to the HTTP header:

  curl https://api.firstofficer.io/v2/mrr/201602 \
  -H 'Authorization: Token token="YourTokenHere"'


  curl https://api.firstofficer.io/v2/mrr/201602 \
  -u YourTokenHere:

When using -u, remember to add : at the end to prevent the password query.

Authenticate your account when using the API by including your secret API key in the request.

You can manage your API keys in FirstOfficer’s Authentication Key Generator. Be sure to keep them secret. Do not share your secret API keys in GitHub, client-side code, and so forth.

All API requests must be made over HTTPS. Calls made over plain HTTP will fail. API requests without authentication will also fail.

Errors

Error Types

invalid_request_error -- Your request has invalid parameters.

Example of error response

{
  "error": {
    "type": "invalid_request_error",
    "message": "Invalid API Key provided."
  }
}

FirstOfficer uses conventional HTTP response codes to indicate the success or failure of an API request.

Error Code Meaning
200 OK – Everything worked as expected.
400 Bad Request – The request was unacceptable, often due to missing or invalid parameter.
401 Unauthorized – No valid API key provided.
404 Not Found – The requested object does not exist.

Error Attributes

Attribute Description
type The type of the error. Can be: “invalid_request_error”
message A human-readable message providing more details about the error.
param The parameter this error relates to. Optional.

Customers

Customers API allows you to retrieve a snapshot of your customer’s metrics. You can also update their data.

FirstOfficer cannot change the data in Stripe, so changes done here will not affect customer billing or their data in Stripe.

The customer object

Example Response

{
    "id":1340573,
    "stripe_id":"cus_1234ABCD",
    "extra_id":null,
    "email":"tester@example.com",
    "name":"John Doe",
    "total_contract_value":629100,
    "current_mrr":69900,
    "current_subscription_count":1,
    "currency":"usd",
    "country": "US", 
    "state": "OH"
}

Attributes

Attribute Description
id integer Customer’s ID in FirstOfficer
stripe_id string Customer’s ID in Stripe
extra_id string Optional internal ID from Stripe metadata, instructions here
email string Customer’s email.
total_contract_value integer The realized customer lifetime value by now. Includes all purchases
current_mrr integer MRR in the current month
current_subscription_count integer Subscription count in the current month. When subscription count is zero, customer is lost. This does not relate to the real-time active/cancelled subscriptions in Stripe, but customer’s status in bookkeeping. Reflects the subscriptions that contributed to MRR.
currency string The currency for this customer, e.g. “usd”, “eur”
country string The country for this customer, e.g. “US”, “FI”
state string The US state for this customer, e.g. “OH”, “CA”. If customer does not reside in the US, the state will be empty.

Create a customer

Example Request


curl -X POST https://api.firstofficer.io/v2/customers  \
-u YourTokenHere: \
-d email="customer@company.com"

Example Response

{
    "id":1340573,
    "stripe_id":"cus_1234ABCD",
    "extra_id":null,
    "email":"tester@example.com",
    "name":"John Doe",
    "total_contract_value":629100,
    "current_mrr":69900,
    "current_subscription_count":1,
    "currency":"usd",
    "country": "US", 
    "state": "OH"
}

HTTP Request

POST https://api.firstofficer.io/v2/customers

Creates a customer.

Arguments

Argument Description
email string The email of the customer, unique. required
name string The name of the customer.
extra_id string Additional ID that will help to identify this customer.

Returns

Returns a customer object if the call succeeded. If arguments are invalid, returns an error.

Retrieve a customer

Example Request


curl https://api.firstofficer.io/v2/customers/cus_1234ABCD  \
-u YourTokenHere:

Example Response

{
    "id":1340573,
    "stripe_id":"cus_1234ABCD",
    "extra_id":null,
    "email":"tester@example.com",
    "name":"John Doe",
    "total_contract_value":629100,
    "current_mrr":69900,
    "current_subscription_count":1,
    "currency":"usd",
    "country": "US", 
    "state": "OH"
}

HTTP Request

GET https://api.firstofficer.io/v2/customers/<id>

Retrieves the details of an existing customer.

Arguments

Argument Description
id string The FirstOfficer ID of the customer to be retrieved. Stripe ID, Extra ID will also work, but are deprecated and will be removed in V3. required

Returns

Returns a customer object if the call succeeded. The extra_id arguments may match to several customers, but only one customer is returned.

If the customer ID does not exist, returns an error.

Update a customer

Example Request


curl -X PUT https://api.firstofficer.io/v2/customers/7598372  \
-u YourTokenHere: \
-d extra_id="Team X"

Example Response

{
    "id":1340573,
    "stripe_id":"cus_1234ABCD",
    "extra_id":"Team X",
    "email":"tester@example.com",
    "name":"John Doe",
    "total_contract_value":629100,
    "current_mrr":69900,
    "current_subscription_count":1,
    "currency":"usd",
    "country": "US", 
    "state": "OH"
}

HTTP Request

PUT https://api.firstofficer.io/v2/customers/<id>

Updates the details of an existing customer. Any parameters not provided will be left unchanged. If there is conflicting data in Stripe, the data in Stripe will override any data set here.

Arguments

Argument Description
id string The FirstOfficer ID of the customer to be retrieved. Stripe ID or Extra ID will also work, but are deprecated and will be removed in V3. required
extra_id string Additional ID that will help to identify this customer. If this argument is omitted, extra_id is not changed.
email string The email of the customer, unique.
name string The name of the customer.

Returns

Returns a customer object if the call succeeded. If the customer ID does not exist, returns an error.

List all customers

Example Request


curl https://api.firstofficer.io/v2/customers?limit=2  \
-u YourTokenHere:

Example Response

{
    "object": "list",
    "has_more": false,
    "data": 
    [
        {
            "id":1340573,
            "stripe_id":"cus_1234ABCD",
            "extra_id":"Team X",
            "email":"tester@example.com",
            "name":"John Doe",
            "total_contract_value":629100,
            "current_mrr":69900,
            "current_subscription_count":1,
            "currency":"usd",
            "country": "US", 
            "state": "OH"
        },
        {
            "id":1340574,
            "stripe_id":"cus_1234ABCE",
            "extra_id":"Team Y",
            "email":"tester2@example.com",
            "name":"Jane Doe",
            "total_contract_value":629100,
            "current_mrr":69900,
            "current_subscription_count":1,
            "currency":"usd",
            "country": "US", 
            "state": "OH"    
        }
    ]
 }

HTTP Request

GET https://api.firstofficer.io/v2/customers

Returns a list of your customers

Arguments

Argument Description
limit optional integer
default is 10
A limit on the number of objects to be returned. Limit can range between 1 and 100 items.
starting_after optional,
customer’s id
A cursor to use in pagination. If there are more plans than can be returned in a single call, you can use
starting_after=id
to retrieve the next page of customers. Id would be the id of the last customer returned in your previous request.

Returns

An array of customers in the data property. Limit the number of customers returned in a single call by using limit argument. Paginate through the customers by using starting_after argument.

This request should never return an error. If no more customers are available, an empty array is returned in data property.

MRR

MRR API allows you to retrieve Monthly Recurring Revenue.

The MRR object

Example Response

{
    "object": "mrr",
    "month":"2016-04-01",
    "mrr":15317,
    "subscriptions":20,
    "change_in_mrr":0,
    "upgrade_mrr":0,
    "downgrade_mrr":0,
    "new_mrr":0,
    "new_customers":0,
    "lost_mrr":0,
    "lost_customers":0,
    "currency":"usd",
    "waiting_mrr":1617110,
    "waiting_subscriptions":204}
}

Attributes

Attribute Description
month ISO date string The first day of the returned month
mrr integer MRR. When retrieved for current month, includes only MRR charged by current date and MRR from pre-paid annual subscriptions. The rest will be found in ‘waiting_mrr’.
subscriptions integer Subscription count, integer. When retrieved for current month, includes only subscriptions charged by current date and old annual subscriptions. The rest will be found in 'waiting_subscriptions’.
change_in_mrr integer Overall change in MRR due to upgrades and downgrades
upgrade_mrr integer MRR from upgrades to higher priced plans and increased seats. Change from monthly to annual plan is counted as an upgrade.
downgrade_mrr integer MRR from downgrades to lower priced plans and decreased seats
new_mrr integer MRR from new and returning customers
new_customers integer Number of new and returning customers
lost_mrr integer MRR from customers who stopped paying
lost_customers integer Number of customers who stopped paying
currency string Currency of this object, e.g. “usd”, “eur”
waiting_mrr integer Expected MRR from subscriptions to be charged. Only shown for current month. The MRR already charged can be found in mrr attribute.
waiting_subscriptions integer Expected subscriptions to be charged. Only shown for current month.

Retrieve all MRRs

Example Request


curl https://api.firstofficer.io/v2/mrr  \
-u YourTokenHere:

Example Response

{
    "data": [
        {
            "object": "mrr",
            "month":"2014-05-01",
            "mrr":33700,
            "subscriptions":3,
            "expansion_mrr":0,
            "contraction_mrr":0,
            "upgrade_mrr":0,
            "downgrade_mrr":0,
            "new_mrr":33700,
            "new_customers":3,
            "lost_mrr":0,
            "lost_customers":0,
            "currency":"usd"
        },
        {
            "object": "mrr",
            "month":"2014-06-01",
            "mrr":61400,
            "subscriptions":7,
            "expansion_mrr":0,
            "contraction_mrr":0,
            "upgrade_mrr":0,
            "downgrade_mrr":0,
            "new_mrr":25700,
            "new_customers":4,
            "lost_mrr":0,
            "lost_customers":0,
            "currency":"usd"
        }
    ]
}

HTTP Request

GET https://api.firstofficer.io/v2/mrr

Retrieves the MRR from all time.

Returns

Returns a JSON array of MRR objects if the call succeeded.

Retrieve Month’s Recurring Revenue

Example Request


curl https://api.firstofficer.io/v2/mrr/2016-02-01  \
-u YourTokenHere:

Example Response

{
    "object": "mrr",
    "month":"2016-04-01",
    "mrr":15317,
    "subscriptions":20,
    "change_in_mrr":0,
    "upgrade_mrr":0,
    "downgrade_mrr":0,
    "new_mrr":0,
    "new_customers":0,
    "lost_mrr":0,
    "lost_customers":0,
    "currency":"usd",
    "waiting_mrr":1617110,
    "waiting_subscriptions":204}
}

HTTP Request

GET https://api.firstofficer.io/v2/mrr/<month in ISO format>

Retrieves the MRR from a single month

Arguments

Argument Description
month ISO date ISO format date, e.g. 2016-04-01. Giving any date from the wanted month is OK and will return the MRR, but we recommend using the first day of the month. required

Returns

Returns a MRR object if the call succeeded. If the month does not have any data, returns and empty JSON.

Invoices

Invoices API allows you to import non-Stripe payments to FirstOfficer.

FirstOfficer cannot change the data in Stripe, so any changes done here will not affect customer billing.

Imported invoices will be processed during the next metrics recalculation, usually within one hour. This means your metrics will not update right away after you’ve imported the invoice.

You will be able to see the imported invoice in customer’s page, which you can access by searching the customer:

https://www.firstofficer.io/customers?stripe_id=cus_ABCD

or

https://www.firstofficer.io/customers?email=partialemailhere@gmail.com

The invoice object

Example Response

{
    "id": "1462443986",
    "subscription_id": "sub_man_2313372_1462443986",
    "object": "invoice",
    "amount_paid": 2900,
    "discount": 0,
    "amount": 2900,
    "currency": "usd",
    "customer": "cus_ABCD",
    "plan": "hobby_monthly",
    "date_paid": "2016-05-05T10:26:26+00:00",
    "date": "2016-05-05T10:26:26+00:00",
    "quantity": 1,
    "period_start": "2016-05-05T10:26:26+00:00",
    "period_end": "2016-06-05T10:26:26+00:00",
    "description": ""
}

Attributes

Attribute Description
id integer Unique identifier.
subscription_id string Identifier of the subscription.
object string Object type, value is “invoice”.
amount_paid integer A positive integer in the smallest currency unit (e.g., 100 cents to charge $1.00) representing the invoiced amount.
discount integer A positive integer representing the discount. Invoice total will be amount - discount.
amount integer A positive integer in the smallest currency unit (e.g., 100 cents to charge $1.00) representing the total amount before discounts.
currency string Currency of the invoice, e.g. ‘usd’, 'eur’.
customer string The ID of the customer.
plan string The ID of the plan. If plan is omitted, payment is booked only into revenue, not to MRR.
date_paid ISO datetime ISO datetime representing when the payment was received.
date ISO datetime ISO datetime representing when invoice was created.
quantity integer The quantity of the seats used.
period_start ISO datetime ISO datetime representing the subscription period start time.
period_end ISO datetime ISO datetime representing the subscription period end time.
description string

Create an invoice

Example Request


curl -X POST https://api.firstofficer.io/v2/invoices \
   -u YourTokenHere: \
   -d customer=cus_ABCD \
   -d plan=hobby_monthly \
   -d amount=4000 

Example Response

{
    "id": "sub_man_2313372_1462443986",
    "object": "invoice",
    "amount_paid": 2900,
    "discount": 0,
    "amount": 2900,
    "currency": "usd",
    "customer": "cus_ABCD",
    "plan": "hobby_monthly",
    "date_paid": "2016-05-05T10:26:26+00:00",
    "date": "2016-05-05T10:26:26+00:00",
    "quantity": 1,
    "period_start": "2016-05-05T10:26:26+00:00",
    "period_end": "2016-06-05T10:26:26+00:00",
    "description": ""
}   

HTTP Request

POST https://api.firstofficer.io/v2/invoices

Creates an invoice for metrics calculation.

You can view the imported invoices at https://www.firstofficer.io/import_payments and see when they get processed. That’s also where you can delete individual invoices if needed.

Argument “plan” defines whether the invoice will be handled as a subscription or as a single purchase. If plan is present, it’s a subscription. If plan is omitted, it’s a one-time payment.

Arguments

Argument Description
customer string The FirstOfficer ID of the customer. Stripe ID will also work, but is deprecated and will be removed in V3. required
plan string The ID of the plan. If plan is omitted, payment is booked only into revenue, not to MRR.
amount integer A positive integer in the smallest currency unit (e.g., 100 cents to charge $1.00) representing the total amount before discounts. Optional when plan given.
date_paid ISO datetime ISO datetime representing when the payment was received. If date_paid is omitted, current time is used.
date ISO datetime ISO datetime representing when the invoice was created. If date is omitted, date_paid is used.
discount integer A positive integer representing the discount. Invoiced amount will be amount - discount.
id integer Unique identifier to prevent the same invoice from being imported twice. If id is omitted, it will be generated.
subscription_id string Use this to continue or upgrade existing subscription or to add quantities to it.
quantity integer The quantity of the seats used. If your plan is €10/user/month, you could pass 5 as the quantity to create an invoice of €50 (5 x €10).
period_start ISO datetime ISO datetime representing the subscription period start time. If period_start is omitted, date is used.
period_end ISO datetime ISO datetime representing the subscription period end time. If period_end is omitted and plan is given, period_end is calculated using the Plan’s interval.
currency string Currency of the invoice, e.g. 'usd’, 'eur’.
description string Free text describing what got invoiced.

Returns

Returns the invoice object if call succeeds.

Returns an error if:

Retrieve an invoice

Example Request


curl https://api.firstofficer.io/v2/invoices/in_123456 \
   -u YourTokenHere: 

Example Response

{
    "id": "in_123456",
    "object": "invoice",
    "amount_paid": 2900,
    "discount": 0,
    "amount": 2900,
    "currency": "usd",
    "customer": "cus_ABCD",
    "plan": "hobby_monthly",
    "date_paid": "2016-05-05T10:26:26+00:00",
    "date": "2016-05-05T10:26:26+00:00",
    "quantity": 1,
    "period_start": "2016-05-05T10:26:26+00:00",
    "period_end": "2016-06-05T10:26:26+00:00",
    "description": ""
}   

HTTP Request

GET https://api.firstofficer.io/v2/invoices/<id>

Retrieves the details of an existing invoice. Only returns invoices created through this API. Retrieve Stripe invoices through the invoices endpoint in Stripe API.

Arguments

Argument Description
id string The ID of the invoice to be retrieved. required

Returns

Returns an invoice object if the call succeeded. Only one invoice is returned.

If the invoice ID does not exist, returns an error.

Delete an invoice

Example Request


curl https://api.firstofficer.io/v2/invoices/in_123456 \
   -u YourTokenHere: \
    -X DELETE

Example Response

{
  "deleted": true,
  "id": "in_123456"
}

HTTP Request

DELETE https://api.firstofficer.io/v2/invoices/<id>

Permanently deletes an invoice. It cannot be undone.

Arguments

Argument Description
id string The ID of the invoice to be deleted. required

Returns

Returns an object with a deleted parameter on success. If the invoice ID does not exist, this call returns an error.

List all invoices

Example Request


curl https://api.firstofficer.io/v2/invoices?limit=2  \
-u YourTokenHere:

Example Response

{
    "object": "list",
    "has_more": false,
    "data": 
    [
        {
            "id": "in_1",
            "object": "invoice",
            "amount_paid": 2900,
            "discount": 0,
            "amount": 2900,
            "currency": "usd",
            "customer": "cus_A",
            "plan": "hobby_monthly",
            "date_paid": "2016-05-05T10:26:26+00:00",
            "date": "2016-05-05T10:26:26+00:00",
            "quantity": 1,
            "period_start": "2016-05-05T10:26:26+00:00",
            "period_end": "2016-06-05T10:26:26+00:00",
            "description": ""
        },
        {
            "id": "in_2",
            "object": "invoice",
            "amount_paid": 2900,
            "discount": 0,
            "amount": 2900,
            "currency": "usd",
            "customer": "cus_B",
            "plan": "hobby_monthly",
            "date_paid": "2016-05-05T10:26:26+00:00",
            "date": "2016-05-05T10:26:26+00:00",
            "quantity": 1,
            "period_start": "2016-05-05T10:26:26+00:00",
            "period_end": "2016-06-05T10:26:26+00:00",
            "description": ""
        }
    ]
 }

HTTP Request

GET https://api.firstofficer.io/v2/invoices

Returns a list of your invoices. Only returns invoices created through this API. List Stripe invoices through the invoices endpoint in Stripe API.

Arguments

Argument Description
limit optional integer
default is 10
A limit on the number of objects to be returned. Limit can range between 1 and 100 items.
starting_after optional,
plan’s id
A cursor to use in pagination. If there are more items than can be returned in a single call, you can use
starting_after=id
to retrieve the next page of items. Id would be the id of the last item returned in your previous request.

Returns

An array of invoices in the data property. Limit the number of invoices returned in a single call by using limit argument. Paginate through the invoices by using starting_after argument.

This request should never return an error. If no more invoices are available, an empty array is returned in data property.

Plans

Plans contains the information for creating subscriptions. Plans API allows you to create and retrieve plans.

FirstOfficer cannot change the data in Stripe, so any changes done here will not affect customer billing.

The plan object

Example Response

  {
    "id": "test",
    "object": "plan",
    "amount": 0,
    "currency": "usd",
    "interval": "month",
    "interval_count": 1,
    "name": "Test Plan"
  }

Attributes

Attribute Description
id string Plan’s unique ID. If plan exists in Stripe, Stripe id is returned.
object string Value is “plan”.
amount positive integer A positive integer in the smallest currency unit (e.g., 100 cents to charge $1.00) representing the total amount before discounts.
name string Display name of the plan.
interval string The billing frequency. Either “day”, “week”, “month” or “year”.
interval_count integer The number of intervals between each subscription billing. For example, interval=month and interval_count=3 means that subscription length is 3 months.
currency string 3-letter ISO code for currency.

Create a plan

Example Request


 curl -X POST https://api.firstofficer.io/v2/plans \
    -u YourTokenHere: \
    -d amount=2000 \
    -d interval=month \
    -d name="The Plan" \
    -d currency=eur \
    -d id="the-plan"

Example Response

 {
   "id": "test",
   "object": "plan",
   "amount": 0,
   "currency": "usd",
   "interval": "month",
   "interval_count": 1,
   "name": "Test Plan"
 }

HTTP Request

POST https://api.firstofficer.io/v2/plans

Creates a plan.

Arguments

Argument Description
id string required
amount positive integer A positive integer in the smallest currency unit (e.g., 100 cents to charge $1.00) representing the total amount before discounts. required
name string Display name of the plan. required
interval string, default is “month” The billing frequency. Either “day”, “week”, “month” or “year”.
interval_count integer,default is 1 The number of intervals between each subscription billing. For example, interval=month and interval_count=3 means that subscription length is 3 months.
currency string, default is “usd” 3-letter ISO code for currency.

Returns

Returns the created plan object if call succeeds. If the plan ID does already exists, returns an error.

Retrieve a plan

Example Request


curl https://api.firstofficer.io/v2/plans/test  \
-u YourTokenHere:

Example Response

{
   "id": "test",
   "object": "plan",
   "amount": 0,
   "currency": "usd",
   "interval": "month",
   "interval_count": 1,
   "name": "Test Plan"
 }

HTTP Request

GET https://api.firstofficer.io/v2/plans/<id>

Retrieves the details of an existing plan.

Arguments

Argument Description
id string The ID of the plan to be retrieved. If the plan is in Stripe, this is the Stripe ID. required

Returns

Returns a plan object if the call succeeded. If the plan ID does not exist, returns an error.

List all plans

You can also view a list of your plans at https://www.firstofficer.io/plans.

Example Request


curl https://api.firstofficer.io/v2/plans?limit=2  \
-u YourTokenHere:

Example Response

{
    "object": "list",
    "has_more": false,
    "data": 
    [
        {
            "id": "test",
            "object": "plan",
            "amount": 0,
            "currency": "usd",
            "interval": "month",
            "interval_count": 1,
            "name": "Test Plan"
        },
        {
            "id": "test_2",
            "object": "plan",
            "amount": 0,
            "currency": "usd",
            "interval": "month",
            "interval_count": 1,
            "name": "Test Plan 2"    
        }
    ]
 }

HTTP Request

GET https://api.firstofficer.io/v2/plans

Returns a list of your plans.

Arguments

Argument Description
limit optional integer
default is 10
A limit on the number of objects to be returned. Limit can range between 1 and 100 items.
starting_after optional,
plan’s id
A cursor to use in pagination. If there are more plans than can be returned in a single call, you can use
starting_after=id
to retrieve the next page of plans. Id would be the id of the last plan returned in your previous request.

Returns

An array of plans in the data property. Limit the number of plans returned in a single call by using limit argument. Paginate through the plans by using starting_after argument.

This request should never return an error. If no more plans are available, an empty array is returned in data property.