Fenerum API (v1)

Download OpenAPI specification:Download

Getting started with Fenerum API

This page will help you get started with Fenerum. You'll be up and running in a jiffy! If you are looking for full API Reference check here.

Interactive API

Simple API explorer can be found when opening API links directly in the browser: https://app.fenerum.com/api/v1/

For the interactive API console you can go to https://app.fenerum.com/api/swagger/

On each endpoint you will find a button

button

which will point you to the same endpoint in the interactive API console.

Next steps

To learn more about common integration flows check out our guides:

or dive deep into our full API reference: API Reference.

In case of any problems don't hesitate to reach out to us at support@fenerum.com.

Authentication

In order to use our API you need to authorize yourself by specifying an appropriate Authorization header:

Authorization: Token <your token>

Keep your API token secret!
Treat your token in the same way as you wold treat a password.

Token

Security Scheme Type API Key
Header parameter name: Authorization

Creating an API token

If you have access to your Organization settings, you can easily create an API token from the user interface:

  1. Choose Settings > Integrations tab in the menu on the left.
  2. In the Fenerum section on top click a Create API user button.

Create API user button placement

This will generate a new user (named API USER) together with a corresponding authorization token. From now on you will see the api token value instead of the button:

Created token

The new API USER is visible on the Users list:

Created API USER on the user list

By default the API USER has all possible permissions. You can change them by editing it's profile.

That's all! You're now ready to start using our API.

Keep your API token secret!
Treat your token in the same way as you wold treat a password.

Pagination

For resource list views, Fenerum uses page-based pagination with 20 elements included per page.

The results are enveloped with pagination-related fields:

  • count integer
    The total number of elements available in this view (with potential filters applied).

  • next string, url, nullable
    The address tho GET to obtain the next page of results (with potential filters applied).

  • prev string, url, nullable
    The address tho GET to obtain the previous page of results (with potential filters applied).

  • results list
    The list of objects returned by the view. For brevity, this is the only part shown and described in particular resource list views responses.

Filtering

Some of the resource list views supports filtering of elements.

Filtering is implemented by adding proper query parameter to the URL (as a GET parameter).

For example to filter invoices issued for a given account one can call API:

GET /api/v1/invoices/?account=some-account-code

In some cases there exists multiple filters for single field.

The meaning of sufix for filtering:

  • __lt - less than
  • __gt - greater than
  • __lte - less or equal than
  • __gte - greater or equal than

Account workflows

An Account in Fenerum is a named entity who can have one or more subscriptions. It represents clients of your Organization and can be used for both companies and people.

Creating an Account

To create an account POST data to the /accounts/ endpoint. The minimal data required for creating an account:

Endpoint: POST /api/v1/accounts/

{
  "company_name": "Your Company ApS",
  "code": "123",
  "legal_address": "company street",
  "legal_zipcode": "12345",
  "legal_city": "company city",
  "legal_country": "DK"
}

legal_country field value must be an ISO Alpha-2 code

The example response would be:

{
  "uuid": "d6dd8a72-8eea-4aaf-8b0b-8d6aee569fee",
  "company_name": "Your Company ApS",
  "code": "123",
  "legal_address": "company street",
  "legal_zipcode": "12345",
  "legal_city": "company city",
  "legal_country": "DK",
  "legal_vat_number": "",
  "paymentcard_set": [],
  "subscription_set": [],
  "recipient_set": [],
  "draftinvoiceline_set": [],
  "model": "billing.Account",
  "schema": "20190613-default"
}

In the next step you should add an email recipient:

Endpoint: POST /api/v1/recipients/

{
  "account": "d6dd8a72-8eea-4aaf-8b0b-8d6aee569fee",
  "name": "Mads Andersen",
  "email": "mads@account-company.com",
  "receive_invoice": true,
  "receive_payment_confirmation": true,
  "receive_subscription_notifications": true 
}

And that's all. You've successfully created a new account that will receive emails from us. Congrats!

Handling subscriptions

Primer

Let's start with introducing a couple of objects:

  • Plan
    Plan is a product or service that an Organization (your company) offers.

  • PlanTerms
    This object represents a concrete set of conditions a product or service (a Plan) can be subscribed to with.

    It allows:

    • setting various intervals (billing periods) counted in days, months or years

    • setting a price in any currency

    • determining whether the charging is done forwards (ahead-of-time, so on the first day of subscription billing period) or backwards (on the last day of subscription billing period)

      PlanTerms that have been used at least once by a Subscription can't be removed - they can be deactivated instead to not allow for starting new subscriptions using them.

  • Subscription
    This object represents a usage of a PlanTerms by a customer (Account).

Creating Subscriptions

There are two ways to create a new subscription for an account:

  1. Through subscriptions/ endpoint
  2. Through account/{code}/subscribe/ endpoint

There are important differences between these endpoints which we discuss in more details below.

Create a new Subscription

Endpoint: POST /api/v1/subscriptions/

This endpoint is a typical way of creating a new object. You need to provide all the required information for a new subscription.

This endpoint will simply create a new object in the database.

Subscriptions that may already exist won't be touched.

Example request:

{
    "account": "account_code",
    "terms": "f4293c5e-b592-43a1-9c68-eb76f62f6250",
    "quantity": 5,
    "collection_method": "invoice",
    "start_date": "2019-10-2861T12:00",
    "group_on_invoice": false,
    "po_number": "0001"
}

Subscribe an Account to a Plan

Using this endpoint has a different flow:

  • if there already is (exactly one) subscription for this account → try to update it with provided data.
    • if the update fails → cancel the existing subscription and create a new one.
  • if there are more then one subscriptions → cancel all of them and create a new one.
  • f there are no subscriptions → create a new one.

This endpoint will make a prorated invoice immediately if there is a subscription being replaced on the account (i.e. cancellation took place).

Furthermore, the payload for this endpoint takes only four keys: terms, quantity, collection_method and group_on_invoice. If you wish to specify more attributes you can make a subsequent PATCH request on the created subscription (see section about updating subscriptions).

Endpoint: POST /api/v1/accounts/{account_code}/subscribe/

Example request:

{
    "terms": "f4293c5e-b592-43a1-9c68-eb76f62f6250",
    "quantity": 1,
    "collection_method": "invoice",
    "group_on_invoice": false
}

In response to both of these endpoint you will get the details of created subscription:

Updating Subscriptions

We provide two methods for subscription updates: PUT and PATCH.

Right now using PUT is equivalent to using PATCH i.e. you can specify only the fields you want to change. In the next version of our API, using PUT method will require to specify all fields explicitly (in accordance with good REST practices).

The flow for updates is the following:

  • try to update the subscription with provided data.
    • if the update fails → cancel the subscription and create a new one.

Note that only the subscription you want to change could end up being cancelled. If other susbscriptions for that account exist they won't be touched

When the update can fail?

The update is not permitted when:

  1. You are trying to set a new plan terms that have a different currency then the existing ones.
  2. You are trying to set a new plan terms on a subscription with pre_renewal_invoicing = True.

In addition to Subscription attributes this endpoint specifies also an optional boolean field prorate which, when set to false, will prevent subscriptions using forward-charging plans from issuing prorate invoices if only their quantity was changed.

If you set prorate to false and the update fails, the subscription won't be cancelled and you will receive 400 error.

How to find terms uuid

If you don't know the uuid of the PlanTerm you want to use you can hit the Plan list endpoint:

Endpoint: GET /api/v1/plans/

Example response:

{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "uuid": "8e63c514-ba33-48da-97ad-4c43713ccf5f",
      "name": "representative",
      "code": "254f49db-a9d8-4b58-bed9-aa4aa9b01155",
      "collect_vat": true,
      "vat_type": "unknown",
      "planterms_set": [
        {
          "uuid": "31406c29-7933-4cea-be4a-bc6964657a42",
          "interval_type": "month",
          "interval_count": 2,
          "price": "445.07",
          "currency": "EUR",
          "backwards_charging": false,
          "active": true,
          "revenue_group": null,
          "model": "billing.PlanTerms",
          "schema": "20190613-default"
        },
        {
          "uuid": "712d53c5-8fd1-4dff-a31a-0d3d2758ab14",
          "interval_type": "month",
          "interval_count": 10,
          "price": "912.53",
          "currency": "EUR",
          "backwards_charging": false,
          "active": true,
          "revenue_group": null,
          "model": "billing.PlanTerms",
          "schema": "20190613-default"
        },
        {
          "uuid": "46d4c7b7-e977-4d4d-a403-f4ddd9695960",
          "interval_type": "month",
          "interval_count": 29,
          "price": "830.49",
          "currency": "EUR",
          "backwards_charging": false,
          "active": true,
          "revenue_group": null,
          "model": "billing.PlanTerms",
          "schema": "20190613-default"
        }
      ],
      "model": "billing.Plan",
      "schema": "20190613-default"
    }
  ]
}

Payment cards workflows

Payment Cards cover both credit and debit cards attached to an account.

Currently supported providers:

Creating a Payment Card

This endpoint is meant for registering in Fenerum a card that already exists in a provider's system.

In the token field of a payload you need to provide an identifier of a card. For Stripe this would mean a Payment Method ID, for QuickPay this would be a subscription id.

All possible token types are described in create card API docs'

Endpoint: POST /api/v1/paymentcards/

{
    "account": "50e9aa0b-8d35-4da7-9a9b-8a35b11579b2",
    "token": "pm_123456789",
    "gateway": "stripe_new"
}

In response you will receive created PaymentCard data:

{
    "uuid": "09655a26-12e0-4a82-8524-7851998886fc",
    "active": true,
    "brand": "Visa",
    "card_number": "XXXXXXXXXXXX4242",
    "month": 1,
    "year": 2020,
    "name": "test@fenerum.com",
    "payment_gateway": "stripe_new",
    "payment_gateway_id": "card_1DcDzT41f9iZfpJVnfDHQY8p",
    "account": "50e9aa0b-8d35-4da7-9a9b-8a35b11579b2"
}

Remember that in order to create a PaymentCard objects you need to set provider's API tokens in your Organization's settings.

Enabling your customer to register a card themselves

Alternatively you can prompt your user to register their card. Through our API you can obtain an url which you can then send to your customer. The url will redirect them to the relevant PSP's form where they will be able to put their credit card data. Fenerum will automatically register their card when they fill in the form.

Endpoint: GET /api/v1/accounts/{code}/card_registration_link/{gateway}/

Disabling a card

To disable a PaymentCard simply perform a POST request with empty payload:

Endpoint: POST /api/v1/paymentcards/{card_uuid}/disable

NOTE: This will apply only to Fenerum, it will not change a card data in the provider's system.

API Reference

This is a full API reference for the Fenerum. It describes every action which is possible using Fenerum REST API.

ERPAccountBudget

account-budgets_list

button

Authorizations:
query Parameters
page
integer

A page number within the paginated result set.

page_size
integer

Number of results to return per page.

Responses

200
get /account-budgets/
https://app.fenerum.com/api/v1/account-budgets/

Request samples

Copy
curl --request GET \
  --url 'https://app.fenerum.com/api/v1/account-budgets/?page=SOME_INTEGER_VALUE&page_size=SOME_INTEGER_VALUE' \
  --header 'authorization: REPLACE_KEY_VALUE'

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "count": 0,
  • "previous": "http://example.com",
  • "results":
    [
    ]
}

account-budgets_read

button

Authorizations:
path Parameters
id
required
integer

A unique integer value identifying this erp account budget.

Responses