API pricing: internal currency (coins, credits, etc)

Overview
A credit-based pricing model, otherwise known as internal or virtual currency, is widely adopted in “Swiss Army Knife”-kind of API products that provide a rich set of APIs for many applications.
If you’re an API developer or considering developing an API and making money with it, this pricing model might be a good fit.
The idea is simple: the user buys some amount of internal currency upfront, be it “coins”, “atoms”, “credits” or anything else. Each call to an API endpoint consumes some number of these units. Calls to different APIs can all consume the same amount of internal currency, or each endpoint can have its own price.
Pros
- If you’re creative with the name of the currency, it adds something unique to your product.
- It creates a feel of ecosystem.
- It’s easy to integrate new endpoints into the pricing model.
Cons
If pricing model is somewhat complex, it can be confusing for the customers, as it will be hard to predict the total cost.
Implementation
In its simplest form, it can be just a row in a database storing the current balance available to the customer. Whenever a payment is made, the balance is increased, when the customer calls an endpoint, the balance is decreased by the cost of the call.
One of the things important to keep in mind is concurrency. If two calls reach your API at the very same moment and there is enough balance for only one API call, the second one can still pass if both calls read the same number from the database and think there is enough balance for them.
If there were 10 concurrent calls, they all would pass for the price of one.
In order to prevent overdrafts, the row should be exclusively locked each time when a manipulation with the balance is implied.
More complex scenarios require sophisticated solutions
If you want currency units to expire after some time (e.g. customers buy 1000 tokens which expire in 6 months), then some process on your side should track the expiration dates and deduct the expired amounts from the balance.
If the balance should be automatically topped up every month (e.g. 1000 credits monthly for $10 per month), then there should be some mechanism in place to ensure recurring monthly payments from the customer and reset the balance.
In such cases it’s more advantageous to implement an append-only architecture
Instead of updating the row with the balance each time it changes, a new row is inserted into the database, capturing the change. If the balance increases (a payment has been made), you insert +100 and the date, if the balance decreases (a call to API has been made), you insert -1.
In order to calculate the actual balance, you sum all records.
Pros
- Traceability of all balance changes. You can see how, when and why the balance was changed. Of course, for that you need to store some additional information with each row.
- Easy to correct mistakes. If a payment was recorded in your system twice due to, for instance, a network hiccup resulting in a double delivery of a webhook call from your payment service provider, you can correct that by inserting another row with the negated amount of the double-counted payment.
- If PostgreSQL is used, insert-only means less work for Autovacuum process (see comment about “Allow inserts, not only updates and deletes, to trigger vacuuming activity in autovacuum”)
Cons
- Takes more time to implement, needs some experience.
- Larger table size.
- Effects of concurrent calls still need to be taken into account.
Implement internal currency in a few clicks
With Project X, credit-based pricing model can be configured in a couple of simple steps.
After you added a new API product and selected API endpoints to be included, you create a quota called, say, “Coins” and specify the number of coins included in the product, the recurring period — a period when the quota is reset — and the endpoints calls to which will consume the coins.

Then you create a price for that quota with the same billing period, and now it’s up to you how you want to charge for the coins.
It can be:
- Standard pricing: charge the same price per coin, regardless of how many coins the customer purchases.
- Package pricing: charge on a per-package basis. If a package consists of 10 coins, then, even if the customer buys 5 coins, he’s still charged for the whole package.
- Graduated pricing: charge different prices for different tiers.
Example: for the first ten coins you charge $1 per coin, for the next 11 to 20 coins you charge $0.5 per coin, etc. - Volume pricing: charge different prices based on the total number of coins purchased/used.
Example: if a customer buys 10 coins in total, you charge $1 per coin. If a customer buys 30 coins, you charge $0.5. If a customer buys more than 30 coins, you charge $0.1.

That’s it. Now get a checkout link from the Product dashboard and pass it to your customers, so they can subscribe to your product, pay and start using the coins. Project X will make sure to collect payments, prevent overdrafts and top up the balance each month.