Skip to content
noBSredir

Portfolios

Requires a Pro plan or higher.

All portfolio endpoints are scoped to a workspace: /api/workspaces/:wsId/portfolios.

Portfolios are public pages that display a curated set of links with live analytics. The public page is accessible at /p/{slug} without authentication.

POST /workspaces/:wsId/portfolios

Create a portfolio.

Role: editor+

Terminal window
curl -X POST https://nobsredir.com/api/workspaces/ws_abc123/portfolios \
-H "X-API-Key: nobs_your_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Q1 Campaign Links",
"slug": "q1-campaign",
"description": "All links for the Q1 2026 marketing campaign",
"config": {
"show_clicks": true,
"style": {
"bg_color": "#0a0a0a",
"text_color": "#e5e5e5",
"accent_color": "#3b82f6"
}
}
}'

Body:

FieldTypeRequiredDescription
namestringyesPortfolio name, max 100 characters.
slugstringnoURL slug for the public page. Lowercase letters, numbers, hyphens, underscores. Max 50 characters. Auto-generated if omitted.
descriptionstringnoDescription shown on the public page.
configobjectnoDisplay and styling options.
config.show_clicksbooleannoShow click counts on public page (default: true).
config.show_trendbooleannoShow click trend on public page.
config.styleobjectnoCustom colors: bg_color, text_color, accent_color (hex values).

Response 201:

{
"id": "pf_abc123",
"name": "Q1 Campaign Links",
"slug": "q1-campaign",
"description": "All links for the Q1 2026 marketing campaign",
"config": {"show_clicks": true, "style": {"bg_color": "#0a0a0a", "text_color": "#e5e5e5", "accent_color": "#3b82f6"}},
"created_at": "2026-03-09T12:00:00.000Z"
}

Errors:

  • 400 - Name is required
  • 400 - Invalid slug format
  • 400 - Slug exceeds 50 characters
  • 402 - Plan limit reached (Pro: 3, Team: 10, Agency: 25)
  • 402 - Portfolios require a Pro plan or higher
  • 409 - Slug already exists

GET /workspaces/:wsId/portfolios

List all portfolios in the workspace.

Role: viewer+

Terminal window
curl https://nobsredir.com/api/workspaces/ws_abc123/portfolios \
-H "X-API-Key: nobs_your_key"

Response 200:

{
"portfolios": [
{
"id": "pf_abc123",
"workspace_id": "ws_abc123",
"name": "Q1 Campaign Links",
"slug": "q1-campaign",
"description": "All links for the Q1 2026 marketing campaign",
"config": {"show_clicks": true},
"created_by": "usr_abc123",
"created_at": "2026-03-09T12:00:00.000Z",
"updated_at": "2026-03-09T12:00:00.000Z"
}
]
}

GET /workspaces/:wsId/portfolios/:portfolioId

Get a portfolio with its links.

Role: viewer+

Terminal window
curl https://nobsredir.com/api/workspaces/ws_abc123/portfolios/pf_abc123 \
-H "X-API-Key: nobs_your_key"

Response 200:

{
"id": "pf_abc123",
"workspace_id": "ws_abc123",
"name": "Q1 Campaign Links",
"slug": "q1-campaign",
"description": "All links for the Q1 2026 marketing campaign",
"config": {"show_clicks": true},
"created_by": "usr_abc123",
"created_at": "2026-03-09T12:00:00.000Z",
"updated_at": "2026-03-09T12:00:00.000Z",
"links": [
{
"id": "lnk_xyz789",
"domain": "go.yourco.com",
"slug": "demo",
"target": "https://example.com/page",
"title": "Demo page",
"click_count": 142,
"sort_order": 0
}
]
}

Errors: 404 - Portfolio not found.


PATCH /workspaces/:wsId/portfolios/:portfolioId

Update a portfolio’s name, description, or config.

Role: editor+

Terminal window
curl -X PATCH https://nobsredir.com/api/workspaces/ws_abc123/portfolios/pf_abc123 \
-H "X-API-Key: nobs_your_key" \
-H "Content-Type: application/json" \
-d '{"name": "Q1 Campaign Links (Updated)", "config": {"show_clicks": false}}'

Body:

FieldTypeRequiredDescription
namestringnoNew name, max 100 characters.
descriptionstring or nullnoNew description. Set to null to clear.
configobjectnoNew display/styling config.

Response 200:

{"ok": true}

Errors: 400 - No updates provided. 404 - Portfolio not found.


DELETE /workspaces/:wsId/portfolios/:portfolioId

Delete a portfolio and its public page. Does not delete the links themselves.

Role: admin+

Terminal window
curl -X DELETE https://nobsredir.com/api/workspaces/ws_abc123/portfolios/pf_abc123 \
-H "X-API-Key: nobs_your_key"

Response 200:

{"ok": true}

Errors: 404 - Portfolio not found.


POST /workspaces/:wsId/portfolios/:portfolioId/links

Add links to a portfolio. Links must belong to the same workspace.

Role: editor+

Terminal window
curl -X POST https://nobsredir.com/api/workspaces/ws_abc123/portfolios/pf_abc123/links \
-H "X-API-Key: nobs_your_key" \
-H "Content-Type: application/json" \
-d '{"link_ids": ["lnk_xyz789", "lnk_abc456"]}'

Body:

FieldTypeRequiredDescription
link_idsstring[]yesArray of link IDs to add. Max 50 per request.

Links that don’t belong to the workspace are silently skipped. Duplicate links (already in the portfolio) are silently skipped.

Response 200:

{"added": 2}

Errors: 400 - Empty or missing link_ids array. 400 - More than 50 links. 404 - Portfolio not found.


DELETE /workspaces/:wsId/portfolios/:portfolioId/links/:linkId

Remove a link from a portfolio. Does not delete the link itself.

Role: editor+

Terminal window
curl -X DELETE https://nobsredir.com/api/workspaces/ws_abc123/portfolios/pf_abc123/links/lnk_xyz789 \
-H "X-API-Key: nobs_your_key"

Response 200:

{"ok": true}

Errors: 404 - Portfolio not found.


Public page

The public portfolio page is available at:

https://yourdomain.com/p/{slug}

No authentication is required. The page displays the portfolio’s links with optional click counts and custom styling. It is cached for 5 minutes.