Read your teams, projects, feedback, and notifications programmatically. Simple, predictable JSON over HTTPS.
The API authenticates with a personal access token. Create one from Settings → API keys inside the app — you'll see the token once, so copy it immediately.
Send it as a bearer token on every request:
Authorization: Bearer <your-token>
The base URL for all endpoints is:
https://bubblenote.app/api
All requests must be made over HTTPS. Tokens can be named and given an expiry (30/60/90 days, a custom date, or no expiration) and revoked at any time.
A token belongs to you and can read anything you can already see in the app, across all of your teams. If you don't have access to a team, project, or piece of feedback, the API won't return it either.
403.
Requests are limited to 60 per minute per token. The
X-RateLimit-Remaining response header tells you how many you have
left; exceeding the limit returns 429 Too Many Requests.
/api/teams
Returns every team you can access. Use a team's id to list its projects.
Example request
curl https://bubblenote.app/api/teams \
-H "Authorization: Bearer <your-token>"
Example response
{
"data": [
{
"id": 7,
"name": "Acme Inc",
"created_at": "2026-05-01T10:00:00.000000Z",
"updated_at": "2026-06-20T14:30:00.000000Z"
}
]
}
/api/teams/{team}/projects
Returns every project in the given team that you can access.
Example request
curl https://bubblenote.app/api/teams/7/projects \
-H "Authorization: Bearer <your-token>"
Example response
{
"data": [
{
"id": 3,
"name": "Acme Checkout",
"domain": "acme.test",
"is_active": true,
"url": "https://bubblenote.app/projects/3",
"feedback_count": 42,
"created_at": "2026-05-01T10:00:00.000000Z",
"updated_at": "2026-06-20T14:30:00.000000Z"
}
]
}
/api/teams/{team}/projects/{project}/feedbacks
Returns a paginated list of feedback for the given project, newest first.
Query parameters
| Parameter | Description |
|---|---|
status |
Filter by one or more statuses:
new, reviewed,
resolved, archived.
Pass a comma-separated list (status=new,resolved) or
repeat the key (status[]=new&status[]=resolved).
|
include |
Embed related comments. One or more of
publicComments,
internalComments
(comma-separated or repeated).
|
Example request
curl "https://bubblenote.app/api/teams/7/projects/3/feedbacks?status=new,resolved&include=publicComments" \ -H "Authorization: Bearer <your-token>"
Example response
{
"data": [
{
"id": 12,
"status": "new",
"comment": "The submit button is misaligned on mobile.",
"page_url": "https://acme.test/checkout",
"submitter_name": "Jane Doe",
"submitter_email": "[email protected]",
"browser": "Chrome 120.0",
"os": "macOS 14.2",
"device": "Desktop",
"country": "US",
"city": "San Francisco",
"is_restricted": false,
"created_at": "2026-06-20T14:30:00.000000Z",
"updated_at": "2026-06-21T09:15:00.000000Z",
"public_comments": [
{
"id": 5,
"body": "Thanks — we're on it!",
"is_internal": false,
"author": "Alex Rivera",
"created_at": "2026-06-21T09:15:00.000000Z"
}
]
}
],
"links": { "first": "...", "last": "...", "prev": null, "next": null },
"meta": { "current_page": 1, "per_page": 25, "total": 1 }
}
Pass ?page=2 to page through results. Internal comments are only
returned to users with access to the project.
/api/notifications
Returns a paginated list of your notifications, newest first.
Query parameters
| Parameter | Description |
|---|---|
status |
Filter by read state: read or unread. |
project_id |
Only notifications related to the given project. |
team_id |
Only notifications related to projects in the given team. |
Example request
curl "https://bubblenote.app/api/notifications?status=unread" \ -H "Authorization: Bearer <your-token>"
Example response
{
"data": [
{
"id": "9f8c1e2a-...",
"type": "new_feedback_received",
"data": { "feedback_id": 12, "project_id": 3 },
"read_at": null,
"created_at": "2026-06-20T14:30:00.000000Z"
}
],
"links": { "first": "...", "last": "...", "prev": null, "next": null },
"meta": { "current_page": 1, "per_page": 25, "total": 1 }
}
The API uses standard HTTP status codes and returns JSON error bodies.
| Status | Meaning |
|---|---|
401 |
Missing, invalid, revoked, or expired token. |
403 |
You don't have access to the requested team or resource. |
404 |
The resource doesn't exist or isn't in the given team. |
422 |
A query parameter was invalid (e.g. an unknown status or include value). |
429 |
Rate limit exceeded — slow down and retry. |