MENU navbar-image

Introduction

External API for integrating with Boxflow. Access tenant data, messages, and attachments programmatically.

# Introduction

The Boxflow External API allows you to programmatically access your workspace data, messages, and attachments.

## Authentication

All API requests require authentication using a Bearer token. You can generate an API token from your user profile in Boxflow.

Include the token in the `Authorization` header:
```
Authorization: Bearer your-api-token-here
```

## Base URL

All API requests should be made to: `https://boxflow.be/api/external`

## Rate Limiting

API requests are rate-limited to prevent abuse. If you exceed the rate limit, you'll receive a 429 response.

Authenticating requests

To authenticate requests, include an Authorization header with the value "Bearer your-api-token-here".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

You can generate an API token from your user profile in Boxflow. Go to your profile settings and create a new API token.

Endpoints

GET api/external/tenants

requires authentication

Example request:
curl --request GET \
    --get "https://boxflow.be/api/external/tenants" \
    --header "Authorization: Bearer your-api-token-here" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"tenant_ids\": [
        16
    ],
    \"page\": 22,
    \"per_page\": 7,
    \"includeUsage\": true,
    \"includeCompanies\": true
}"
const url = new URL(
    "https://boxflow.be/api/external/tenants"
);

const headers = {
    "Authorization": "Bearer your-api-token-here",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "tenant_ids": [
        16
    ],
    "page": 22,
    "per_page": 7,
    "includeUsage": true,
    "includeCompanies": true
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://boxflow.be/api/external/tenants';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer your-api-token-here',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'tenant_ids' => [16],
            'page' => 22,
            'per_page' => 7,
            'includeUsage' => true,
            'includeCompanies' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://boxflow.be/api/external/tenants'
payload = {
    "tenant_ids": [
        16
    ],
    "page": 22,
    "per_page": 7,
    "includeUsage": true,
    "includeCompanies": true
}
headers = {
  'Authorization': 'Bearer your-api-token-here',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, json=payload)
response.json()

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/external/tenants

Headers

Authorization        

Example: Bearer your-api-token-here

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

tenant_ids   integer[]  optional    

Must be at least 1.

page   integer  optional    

Must be at least 1. Example: 22

per_page   integer  optional    

Must be at least 1. Must not be greater than 100. Example: 7

includeUsage   boolean  optional    

Example: true

includeCompanies   boolean  optional    

Example: true

GET api/external/subscriptions

requires authentication

Example request:
curl --request GET \
    --get "https://boxflow.be/api/external/subscriptions" \
    --header "Authorization: Bearer your-api-token-here" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"tenant_ids\": [
        16
    ],
    \"plan_ids\": [
        22
    ],
    \"status\": \"inactive\",
    \"page\": 67,
    \"per_page\": 16
}"
const url = new URL(
    "https://boxflow.be/api/external/subscriptions"
);

const headers = {
    "Authorization": "Bearer your-api-token-here",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "tenant_ids": [
        16
    ],
    "plan_ids": [
        22
    ],
    "status": "inactive",
    "page": 67,
    "per_page": 16
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://boxflow.be/api/external/subscriptions';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer your-api-token-here',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'tenant_ids' => [16],
            'plan_ids' => [22],
            'status' => 'inactive',
            'page' => 67,
            'per_page' => 16,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://boxflow.be/api/external/subscriptions'
payload = {
    "tenant_ids": [
        16
    ],
    "plan_ids": [
        22
    ],
    "status": "inactive",
    "page": 67,
    "per_page": 16
}
headers = {
  'Authorization': 'Bearer your-api-token-here',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, json=payload)
response.json()

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/external/subscriptions

Headers

Authorization        

Example: Bearer your-api-token-here

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

tenant_ids   integer[]  optional    

Must be at least 1.

plan_ids   integer[]  optional    

Must be at least 1.

status   string  optional    

Example: inactive

Must be one of:
  • active
  • inactive
  • pending
  • canceled
  • past_due
page   integer  optional    

Must be at least 1. Example: 67

per_page   integer  optional    

Must be at least 1. Must not be greater than 100. Example: 16

POST api/external/transactions

requires authentication

Example request:
curl --request POST \
    "https://boxflow.be/api/external/transactions" \
    --header "Authorization: Bearer your-api-token-here" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"subscription_id\": 16,
    \"amount\": 22,
    \"total_tax\": 84,
    \"total_discount\": 12,
    \"total_fees\": 77,
    \"description\": \"Et fugiat sunt nihil accusantium.\",
    \"transaction_date\": \"2026-09-11T13:51:20\"
}"
const url = new URL(
    "https://boxflow.be/api/external/transactions"
);

const headers = {
    "Authorization": "Bearer your-api-token-here",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "subscription_id": 16,
    "amount": 22,
    "total_tax": 84,
    "total_discount": 12,
    "total_fees": 77,
    "description": "Et fugiat sunt nihil accusantium.",
    "transaction_date": "2026-09-11T13:51:20"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://boxflow.be/api/external/transactions';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer your-api-token-here',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'subscription_id' => 16,
            'amount' => 22,
            'total_tax' => 84,
            'total_discount' => 12,
            'total_fees' => 77,
            'description' => 'Et fugiat sunt nihil accusantium.',
            'transaction_date' => '2026-09-11T13:51:20',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://boxflow.be/api/external/transactions'
payload = {
    "subscription_id": 16,
    "amount": 22,
    "total_tax": 84,
    "total_discount": 12,
    "total_fees": 77,
    "description": "Et fugiat sunt nihil accusantium.",
    "transaction_date": "2026-09-11T13:51:20"
}
headers = {
  'Authorization': 'Bearer your-api-token-here',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Request      

POST api/external/transactions

Headers

Authorization        

Example: Bearer your-api-token-here

Content-Type        

Example: application/json

Accept        

Example: application/json

Body Parameters

subscription_id   integer     

Must match an existing stored value. Example: 16

amount   integer     

Must be at least 1. Example: 22

total_tax   integer  optional    

Must be at least 0. Example: 84

total_discount   integer  optional    

Must be at least 0. Example: 12

total_fees   integer  optional    

Must be at least 0. Example: 77

description   string  optional    

Must not be greater than 500 characters. Example: Et fugiat sunt nihil accusantium.

transaction_date   string  optional    

Must be a valid date. Example: 2026-09-11T13:51:20

PATCH api/external/subscriptions/{subscriptionId}/mrr-override

requires authentication

Example request:
curl --request PATCH \
    "https://boxflow.be/api/external/subscriptions/architecto/mrr-override" \
    --header "Authorization: Bearer your-api-token-here" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"mrr_override\": 27
}"
const url = new URL(
    "https://boxflow.be/api/external/subscriptions/architecto/mrr-override"
);

const headers = {
    "Authorization": "Bearer your-api-token-here",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "mrr_override": 27
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://boxflow.be/api/external/subscriptions/architecto/mrr-override';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer your-api-token-here',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'mrr_override' => 27,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://boxflow.be/api/external/subscriptions/architecto/mrr-override'
payload = {
    "mrr_override": 27
}
headers = {
  'Authorization': 'Bearer your-api-token-here',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('PATCH', url, headers=headers, json=payload)
response.json()

Request      

PATCH api/external/subscriptions/{subscriptionId}/mrr-override

Headers

Authorization        

Example: Bearer your-api-token-here

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

subscriptionId   string     

Example: architecto

Body Parameters

mrr_override   integer  optional    

Must be at least 0. Example: 27

PATCH api/external/subscriptions/{subscriptionId}/enterprise-billing

requires authentication

Example request:
curl --request PATCH \
    "https://boxflow.be/api/external/subscriptions/architecto/enterprise-billing" \
    --header "Authorization: Bearer your-api-token-here" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"enterprise_amount_per_company\": 27,
    \"enterprise_minimum_companies\": 39
}"
const url = new URL(
    "https://boxflow.be/api/external/subscriptions/architecto/enterprise-billing"
);

const headers = {
    "Authorization": "Bearer your-api-token-here",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "enterprise_amount_per_company": 27,
    "enterprise_minimum_companies": 39
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://boxflow.be/api/external/subscriptions/architecto/enterprise-billing';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer your-api-token-here',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'enterprise_amount_per_company' => 27,
            'enterprise_minimum_companies' => 39,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://boxflow.be/api/external/subscriptions/architecto/enterprise-billing'
payload = {
    "enterprise_amount_per_company": 27,
    "enterprise_minimum_companies": 39
}
headers = {
  'Authorization': 'Bearer your-api-token-here',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('PATCH', url, headers=headers, json=payload)
response.json()

Request      

PATCH api/external/subscriptions/{subscriptionId}/enterprise-billing

Headers

Authorization        

Example: Bearer your-api-token-here

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

subscriptionId   string     

Example: architecto

Body Parameters

enterprise_amount_per_company   integer  optional    

Must be at least 0. Example: 27

enterprise_minimum_companies   integer  optional    

Must be at least 0. Example: 39

List users for a specific tenant

requires authentication

Example request:
curl --request GET \
    --get "https://boxflow.be/api/external/tenants/architecto/users" \
    --header "Authorization: Bearer your-api-token-here" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"page\": 16,
    \"per_page\": 22,
    \"search\": \"g\"
}"
const url = new URL(
    "https://boxflow.be/api/external/tenants/architecto/users"
);

const headers = {
    "Authorization": "Bearer your-api-token-here",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "page": 16,
    "per_page": 22,
    "search": "g"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://boxflow.be/api/external/tenants/architecto/users';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer your-api-token-here',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'page' => 16,
            'per_page' => 22,
            'search' => 'g',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://boxflow.be/api/external/tenants/architecto/users'
payload = {
    "page": 16,
    "per_page": 22,
    "search": "g"
}
headers = {
  'Authorization': 'Bearer your-api-token-here',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, json=payload)
response.json()

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/external/tenants/{tenant}/users

Headers

Authorization        

Example: Bearer your-api-token-here

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

tenant   string     

The tenant. Example: architecto

Body Parameters

page   integer  optional    

Must be at least 1. Example: 16

per_page   integer  optional    

Must be at least 1. Must not be greater than 100. Example: 22

search   string  optional    

Must not be greater than 255 characters. Example: g

List messages for a specific tenant

requires authentication

Example request:
curl --request GET \
    --get "https://boxflow.be/api/external/tenants/architecto/messages" \
    --header "Authorization: Bearer your-api-token-here" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"status_id\": 16,
    \"service_id\": 22,
    \"company_id\": 67,
    \"sender_id\": 66,
    \"from_date\": \"2026-09-11T13:51:20\",
    \"to_date\": \"2026-09-11T13:51:20\",
    \"search\": \"m\",
    \"page\": 35,
    \"per_page\": 8
}"
const url = new URL(
    "https://boxflow.be/api/external/tenants/architecto/messages"
);

const headers = {
    "Authorization": "Bearer your-api-token-here",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "status_id": 16,
    "service_id": 22,
    "company_id": 67,
    "sender_id": 66,
    "from_date": "2026-09-11T13:51:20",
    "to_date": "2026-09-11T13:51:20",
    "search": "m",
    "page": 35,
    "per_page": 8
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://boxflow.be/api/external/tenants/architecto/messages';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer your-api-token-here',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'status_id' => 16,
            'service_id' => 22,
            'company_id' => 67,
            'sender_id' => 66,
            'from_date' => '2026-09-11T13:51:20',
            'to_date' => '2026-09-11T13:51:20',
            'search' => 'm',
            'page' => 35,
            'per_page' => 8,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://boxflow.be/api/external/tenants/architecto/messages'
payload = {
    "status_id": 16,
    "service_id": 22,
    "company_id": 67,
    "sender_id": 66,
    "from_date": "2026-09-11T13:51:20",
    "to_date": "2026-09-11T13:51:20",
    "search": "m",
    "page": 35,
    "per_page": 8
}
headers = {
  'Authorization': 'Bearer your-api-token-here',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, json=payload)
response.json()

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/external/tenants/{tenant}/messages

Headers

Authorization        

Example: Bearer your-api-token-here

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

tenant   string     

The tenant. Example: architecto

Body Parameters

status_id   integer  optional    

Must be at least 1. Example: 16

service_id   integer  optional    

Must be at least 1. Example: 22

company_id   integer  optional    

Must be at least 1. Example: 67

sender_id   integer  optional    

Must be at least 1. Example: 66

from_date   string  optional    

Must be a valid date. Example: 2026-09-11T13:51:20

to_date   string  optional    

Must be a valid date. Example: 2026-09-11T13:51:20

search   string  optional    

Must not be greater than 255 characters. Example: m

page   integer  optional    

Must be at least 1. Example: 35

per_page   integer  optional    

Must be at least 1. Must not be greater than 100. Example: 8

Get a specific message with all details

requires authentication

Example request:
curl --request GET \
    --get "https://boxflow.be/api/external/tenants/architecto/messages/1" \
    --header "Authorization: Bearer your-api-token-here" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://boxflow.be/api/external/tenants/architecto/messages/1"
);

const headers = {
    "Authorization": "Bearer your-api-token-here",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://boxflow.be/api/external/tenants/architecto/messages/1';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer your-api-token-here',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://boxflow.be/api/external/tenants/architecto/messages/1'
headers = {
  'Authorization': 'Bearer your-api-token-here',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/external/tenants/{tenant}/messages/{id}

Headers

Authorization        

Example: Bearer your-api-token-here

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

tenant   string     

The tenant. Example: architecto

id   integer     

The ID of the message. Example: 1

List attachments for a specific message

requires authentication

Example request:
curl --request GET \
    --get "https://boxflow.be/api/external/tenants/architecto/messages/1/attachments" \
    --header "Authorization: Bearer your-api-token-here" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://boxflow.be/api/external/tenants/architecto/messages/1/attachments"
);

const headers = {
    "Authorization": "Bearer your-api-token-here",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://boxflow.be/api/external/tenants/architecto/messages/1/attachments';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer your-api-token-here',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://boxflow.be/api/external/tenants/architecto/messages/1/attachments'
headers = {
  'Authorization': 'Bearer your-api-token-here',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/external/tenants/{tenant}/messages/{message_id}/attachments

Headers

Authorization        

Example: Bearer your-api-token-here

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

tenant   string     

The tenant. Example: architecto

message_id   integer     

The ID of the message. Example: 1

Download a specific attachment (decrypted from local storage or live service)

requires authentication

Example request:
curl --request GET \
    --get "https://boxflow.be/api/external/tenants/architecto/messages/1/attachments/architecto" \
    --header "Authorization: Bearer your-api-token-here" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://boxflow.be/api/external/tenants/architecto/messages/1/attachments/architecto"
);

const headers = {
    "Authorization": "Bearer your-api-token-here",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://boxflow.be/api/external/tenants/architecto/messages/1/attachments/architecto';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer your-api-token-here',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'https://boxflow.be/api/external/tenants/architecto/messages/1/attachments/architecto'
headers = {
  'Authorization': 'Bearer your-api-token-here',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
access-control-allow-origin: *
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/external/tenants/{tenant}/messages/{message}/attachments/{attachment}

Headers

Authorization        

Example: Bearer your-api-token-here

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

tenant   string     

The tenant. Example: architecto

message   integer     

The message. Example: 1

attachment   string     

The attachment. Example: architecto