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.
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.
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.
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.
Send a request
Every request carries the token in the Authorization header. The answer is JSON, with your data under data.
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.
{
"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".
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];
}=P2PDASH("totalBalance") → 12233.5Sheets 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.
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}")2026-08 94.80
2026-09 96.42
2026-10 98.15XIRR 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.
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);
}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 -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}'{
"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.
summaryAll-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
timeseriesThe 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
metricsXIRR (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-projectionWhat 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
taxInterest, 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 inYYYY-MM-DD, both included. Withmonthoryearthey widen to whole periods. The balances still count from your first day of data, so a laterfromdoesn't reset them. granularity- Only for
timeseries.day(default),monthoryear. 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 like2025. 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 documentGood 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.
| Status | Code and meaning |
|---|---|
| 400 | invalid_requestA parameter is wrong. |
| 401 | unauthorizedThe token is missing, mistyped, revoked or expired. |
| 403 | insufficient_scopeThe token isn't allowed to read this part of the API. |
| 404 | not_foundThe path doesn't exist, or the ID belongs to no platform or portfolio of yours. |
| 429 | rate_limited60 requests without a minute's pause. Wait as many seconds as |
| 500 | internal_errorOur 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
curl "https://app.p2pdash.com/api/v1/account/timeseries?from=2025-02-30" \
-H "Authorization: Bearer $P2PDASH_TOKEN"{
"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 TokensNo account yet? Sign up for free and import an export first, otherwise the API has nothing to show.