Sign InSign Up

The P2P Dash API

Your P2P portfolio data as JSON, for a spreadsheet, a script or your own dashboard. You create a token in your account, send it with each request and get back the same numbers you see in P2P Dash.

Read-onlyFreeFirst version

Your first request

Three steps in a terminal on macOS or Linux. If you'd rather start in Google Sheets, the examples below have you covered.

1

Create a token

In P2P Dash, open the user menu and go to "API Tokens". Give the token a name, set "Your data" to Read and pick when it expires. We show the token exactly once, so copy it right away.

2

Keep it out of your code

Put it in an environment variable, here P2PDASH_TOKEN, not in a file you share. Anyone who has the token can read your numbers.

3

Send a request

Every request carries the token in the Authorization header. The answer is JSON, with your data under data.

Request
export P2PDASH_TOKEN="p2pdash_..."

curl https://app.p2pdash.com/api/v1/account/summary \
  -H "Authorization: Bearer $P2PDASH_TOKEN"

On Windows in PowerShell, set the token with $env:P2PDASH_TOKEN = "p2pdash_...", write curl.exe instead of curl, put the request on one line and use $env:P2PDASH_TOKEN in the header.

Response
{
  "data": {
    "platformCount": 4,
    "firstDate": "2021-03-02",
    "lastDate": "2026-11-09",
    "interest": 1781.4,
    "principalRepayment": 37443.05,
    "fee": 12.4,
    "tax": 0,
    "bonus": 85,
    "deposit": 12000,
    "withdrawal": 1500,
    "investment": 48210.33,
    "defaultLoss": 120.5,
    "internalTransfer": 0,
    "transactionCount": 14873,
    "totalBalance": 12233.5,
    "availableBalance": 1586.72,
    "investedBalance": 10646.78,
    "netDeposits": 10500,
    "netIncome": 1733.5
  }
}

These are example figures. totalBalance is what your account is worth: deposits minus withdrawals plus everything you earned, after fees, taxes and losses.

Examples

Four things you can do with the API. Copy the code, set your token, and adjust from there.

Your balance in Google Sheets

In your sheet, open Extensions → Apps Script and paste this function. Under Project settings → Script properties, add P2PDASH_TOKEN with your token. Then type the formula into a cell. Any field of the summary works, e.g. "netIncome".

Google Apps Script
function P2PDASH(field) {
  const token = PropertiesService.getScriptProperties()
    .getProperty("P2PDASH_TOKEN");
  const res = UrlFetchApp.fetch(
    "https://app.p2pdash.com/api/v1/account/summary",
    { headers: { Authorization: "Bearer " + token } },
  );
  return JSON.parse(res.getContentText()).data[field];
}
Output
=P2PDASH("totalBalance")   →  12233.5

Sheets keeps the result and only asks again when the formula changes. To refresh, add a second argument like =P2PDASH("totalBalance", A1) and change A1. Each cell is one request. Anyone who can edit the sheet can also read the token in Apps Script, so don't do this in a sheet others can edit.

Interest per month

The timeseries with granularity=month gives you one point per month with data. Install the library once with pip install requests.

Python
import os
import requests

res = requests.get(
    "https://app.p2pdash.com/api/v1/account/timeseries",
    params={"granularity": "month", "from": "2026-08-01", "to": "2026-10-31"},
    headers={"Authorization": f"Bearer {os.environ['P2PDASH_TOKEN']}"},
)
res.raise_for_status()

for point in res.json()["data"]:
    print(point["date"][:7], f"{point['interest']:.2f}")
Output
2026-08 94.80
2026-09 96.42
2026-10 98.15

XIRR per platform

Save this as xirr.mjs and run node xirr.mjs (Node.js 18 or newer). The XIRR comes as a fraction: 0.0984 means 9.84% per year. A platform without enough data gets null.

JavaScript (Node.js)
const res = await fetch("https://app.p2pdash.com/api/v1/account/metrics", {
  headers: { Authorization: `Bearer ${process.env.P2PDASH_TOKEN}` },
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const { data } = await res.json();

for (const p of data.xirr.platforms) {
  const xirr = p.allTimeXirr === null
    ? "-"
    : (p.allTimeXirr * 100).toFixed(2) + "%";
  console.log(p.name.padEnd(12), xirr);
}
Output
Platform A   9.84%
Platform B   10.37%
Platform C   11.20%
Platform D   -

Figures for your tax return

Interest and bonuses per platform for one year, shortened with jq. Which of them count as income depends on your country's rules; the API only shows what is in P2P Dash.

curl + jq
curl -s "https://app.p2pdash.com/api/v1/account/tax?year=2025" \
  -H "Authorization: Bearer $P2PDASH_TOKEN" \
  | jq '.data[] | {name, interest: .years[0].interest, bonus: .years[0].bonus}'
Output
{
  "name": "Platform A",
  "interest": 412.37,
  "bonus": 25
}
{
  "name": "Platform B",
  "interest": 288.9,
  "bonus": 0
}

What you can read

Your whole account, each portfolio and each platform answer the same five questions. Learn them once and you can ask them at any level.

The five views

Each view exists three times. For one platform, first get its ID from /api/v1/platforms, then put it in place of {id}. Portfolios work the same way.

summary

All-time totals: interest, bonuses, fees, losses, deposits, withdrawals and the balances that follow from them.

Whole account
GET /api/v1/account/summary
One portfolio
GET /api/v1/portfolios/{id}/summary
One platform
GET /api/v1/platforms/{id}/summary
timeseries

The same figures over time, per day, month or year, with the balance at the end of each period. Good for charts.

Whole account
GET /api/v1/account/timeseries
One portfolio
GET /api/v1/portfolios/{id}/timeseries
One platform
GET /api/v1/platforms/{id}/timeseries
metrics

XIRR (all-time and per year, with and without bonuses), cash drag, average invested balance and the capital freedom index, per platform and in total.

Whole account
GET /api/v1/account/metrics
One portfolio
GET /api/v1/portfolios/{id}/metrics
One platform
GET /api/v1/platforms/{id}/metrics
income-projection

What your current balance would earn per day, month and year at your past XIRR without bonuses. A projection, not a promise.

Whole account
GET /api/v1/account/income-projection
One portfolio
GET /api/v1/portfolios/{id}/income-projection
One platform
GET /api/v1/platforms/{id}/income-projection
tax

Interest, bonuses, taxes withheld, fees and losses per platform and calendar year, newest year first.

Whole account
GET /api/v1/account/tax
One portfolio
GET /api/v1/portfolios/{id}/tax
One platform
GET /api/v1/platforms/{id}/tax

Lists and details

GET /api/v1/account
Which token you are using, its scopes and when it expires. Handy for checking that a token still works.
GET /api/v1/platforms
All your platforms with their IDs, portfolios and totals. Start here to find the IDs.
GET /api/v1/platforms/{id}
One platform, the same object as in the list.
GET /api/v1/platforms/{id}/intent-history
When you changed your plan for a platform (grow, hold, exit and so on).
GET /api/v1/portfolios
All your portfolios with their platforms.
GET /api/v1/portfolios/{id}
One portfolio.
GET /api/v1/platform-types
Facts per platform type: country, asset classes, regulation, founding year. The same for every user.

Query parameters

from, to
Only for timeseries. Days in YYYY-MM-DD, both included. With month or year they widen to whole periods. The balances still count from your first day of data, so a later from doesn't reset them.
granularity
Only for timeseries. day (default), month or year. The date of a point is the last day of its period. A day or period without data has no point at all, so don't expect zeros.
year
Only for tax. A calendar year like 2025. Platforms without data in that year are left out.

Every field of every response is listed in the OpenAPI document. Tools like Postman or Swagger UI can read it, and code generators can build a client from it.

Open the OpenAPI document

Good to know

The rules that apply to every endpoint.

Read-only

The API reads your data and changes nothing. Imports and settings still happen in the app.

As current as your last import

P2P Dash doesn't fetch anything from the platforms. The API returns what you imported or entered by hand, and lastDate tells you the latest day with data.

60 requests, then a minute's pause

Per token. The count only starts over once the token has gone a full minute without any request, so a script that asks every few seconds hits the limit too. Then you get a 429, and Retry-After says how many seconds to wait. Successful answers show what's left in X-RateLimit-Remaining.

Amounts in EUR

Money flows like deposit, withdrawal or fee are always positive; the direction is in the name. Balances and netIncome can go below zero. XIRR and cash drag are fractions (0.075 is 7.5%), the capital freedom index runs from 0 to 100.

Dates in UTC

Days as YYYY-MM-DD, points in time as ISO 8601. A day is the day in the export, without time zones moving it.

Tokens

Up to 10 active tokens per account, valid for 30 days, 90 days, a year or without expiry. Revoke a token on the tokens page and it stops working at once.

When something goes wrong

Errors come back as JSON with a fixed error.code. Check the code, not the message: the message can change, the codes stay.

StatusCode and meaning
400invalid_request

A parameter is wrong. details names each field and what's wrong with it.

401unauthorized

The token is missing, mistyped, revoked or expired.

403insufficient_scope

The token isn't allowed to read this part of the API.

404not_found

The path doesn't exist, or the ID belongs to no platform or portfolio of yours.

429rate_limited

60 requests without a minute's pause. Wait as many seconds as Retry-After says.

500internal_error

Our mistake. Try again later, and if it keeps happening, write to us.

Two more 403 codes exist, forbidden and plan_required. With a normal account you won't see them.

Example: a date that doesn't exist

Request
curl "https://app.p2pdash.com/api/v1/account/timeseries?from=2025-02-30" \
  -H "Authorization: Bearer $P2PDASH_TOKEN"
Response
{
  "error": {
    "code": "invalid_request",
    "message": "Not a valid calendar date",
    "details": [
      {
        "field": "from",
        "message": "Not a valid calendar date"
      }
    ]
  }
}

Questions about the API

Before your first request.

Does the API cost anything?

No. Like the app, it is free for every account right now.

Can I import transactions through the API?

Not yet. The API only reads. You still upload your exports in the app.

Do I need to know how to program?

Not much. The Google Sheets example is copy and paste, and the curl request runs in the terminal on macOS and Linux. For anything beyond that, a little Python or JavaScript helps.

What happens if someone gets hold of my token?

They can read your P2P Dash numbers, but they can't change anything, and they never see your email or password. Revoke the token on the tokens page and it stops working immediately.

Will the API change?

Yes, it can. This is the first version, and fields or endpoints may still change without a new version number. If you build something on it, expect to adjust it now and then.

Can I get data from other users?

No. A token only ever reads the data of the account that created it. The one exception is the platform types list, which holds public facts about the platforms.

Create your first token

Log in, open "API Tokens" in the user menu and send your first request.

Go to API Tokens

No account yet? Sign up for free and import an export first, otherwise the API has nothing to show.