B
Biflus Docs
biflus.com Get API key
API ReferenceQuick start

Quick start

The whole API follows one pattern, so seeing it once tells you almost everything.

1

Get an API key

Go to Settings → API keys in your Biflus account and generate one. See Authentication.

2

Make a request

Send it as a bearer token. Here's listing your clients:

curl https://api.biflus.com/v1/clients \
  -H "Authorization: Bearer sk_test_YOUR_API_KEY"
import requests

resp = requests.get(
    "https://api.biflus.com/v1/clients",
    headers={"Authorization": "Bearer sk_test_YOUR_API_KEY"},
)
print(resp.json())
const res = await fetch("https://api.biflus.com/v1/clients", {
  headers: { "Authorization": "Bearer sk_test_YOUR_API_KEY" }
});
const data = await res.json();
using System.Net.Http;
using System.Net.Http.Headers;

var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://api.biflus.com/v1/clients");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "sk_test_YOUR_API_KEY");
var response = await client.SendAsync(request);
var data = await response.Content.ReadAsStringAsync();
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.biflus.com/v1/clients", nil)
	req.Header.Set("Authorization", "Bearer sk_test_YOUR_API_KEY")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
	data, _ := io.ReadAll(resp.Body)
	fmt.Println(string(data))
}
import java.net.URI;
import java.net.http.*;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.biflus.com/v1/clients"))
    .header("Authorization", "Bearer sk_test_YOUR_API_KEY")
    .method("GET", HttpRequest.BodyPublishers.noBody())
    .build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
require 'net/http'
require 'json'

uri = URI("https://api.biflus.com/v1/clients")
req = Net::HTTP::Get.new(uri)
req['Authorization'] = 'Bearer sk_test_YOUR_API_KEY'

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
3

Read the response

Every list comes back the same shape: a data array plus a pagination object.

{
  "data": [
    {
      "_id": "client_a8f291",
      "company_name": "Acme Corp",
      "type": "Company" /* … */
    }
  ],
  "pagination": {
    "count": 1,
    "remaining": 0,
    "next_cursor": null
  }
}

Every other resource works the same way: GET to list, GET .../:id to fetch one, POST to create, PATCH to update, DELETE to remove. If you know one, you know them all.

Best practices
  • Build against sk_test_ first. Test and live keys hit completely separate data, so there's no risk of a bad request touching real invoices while you're still wiring things up.
  • Log the error field on every non-2xx response while you integrate — it's written to be read directly, not just for us.
  • Cache valid_options from a 400 once (icons, units) instead of hardcoding the list — it's returned fresh from the same source of truth the app uses.
Common mistakes
  • Don't guess at field names. Every resource page lists exactly which fields are writable — sending an unlisted field is silently ignored, not rejected, which is easy to mistake for a bug on our end.
  • Don't poll for invoice status changes. Use a webhook instead — it's less code and you'll hear about a payment the moment it happens, not up to a minute later.
  • Don't skip the pagination.next_cursor check. Assuming a list response is complete because it "looked like everything" is the most common cause of missing records in an integration.

Where to go next

This page is updated as the API changes. If something here doesn't match what you're seeing, that's a bug worth flagging to the Biflus team.