productlane

$npx mdskill add vm0-ai/vm0-skills/productlane

Fetch product insights and manage feedback via Productlane API.

  • Retrieves workspace data, company lists, and detailed company profiles.
  • Requires valid Productlane API token for all authentication requests.
  • Executes GET and POST operations to query or create company records.
  • Returns structured JSON responses for programmatic data access.

SKILL.md

.github/skills/productlaneView on GitHub ↗
---
name: productlane
description: Productlane API for feedback management. Use when user mentions "Productlane",
  "feedback", "feature request", or product insights.
---

## Troubleshooting

If requests fail, run `zero doctor check-connector --env-name PRODUCTLANE_TOKEN` or `zero doctor check-connector --url https://productlane.com/api/v1/workspaces --method GET`

## Workspaces

### Get Workspace

Retrieve workspace information. Replace `<workspace-id>` with the actual workspace ID:

```bash
curl -s "https://productlane.com/api/v1/workspaces/<workspace-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

## Companies

### List Companies

```bash
curl -s "https://productlane.com/api/v1/companies?take=20" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### List Companies with Filters

Filter by name or domain:

```bash
curl -s "https://productlane.com/api/v1/companies?name=Acme&take=10" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Get Company by ID

Replace `<company-id>` with the actual company ID:

```bash
curl -s "https://productlane.com/api/v1/companies/<company-id>?groupUpvotes=true" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Create Company

Write to `/tmp/productlane_request.json`:

```json
{
  "name": "Acme Corp",
  "domains": ["acme.com"],
  "size": 50,
  "revenue": 1000000
}
```

Then run:

```bash
curl -s -X POST "https://productlane.com/api/v1/companies" --header "Authorization: Bearer $PRODUCTLANE_TOKEN" --header "Content-Type: application/json" -d @/tmp/productlane_request.json
```

### Update Company

Write to `/tmp/productlane_request.json`:

```json
{
  "name": "Acme Corporation",
  "size": 100
}
```

Then run. Replace `<company-id>` with the actual company ID:

```bash
curl -s -X PATCH "https://productlane.com/api/v1/companies/<company-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN" --header "Content-Type: application/json" -d @/tmp/productlane_request.json
```

### Delete Company

Replace `<company-id>` with the actual company ID:

```bash
curl -s -X DELETE "https://productlane.com/api/v1/companies/<company-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Get Linear Customer Options

Get available Linear customer statuses and tiers. Requires Linear integration with `customer:read` or `customer:write` scope:

```bash
curl -s "https://productlane.com/api/v1/companies/linear-options" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

## Contacts

### List Contacts

```bash
curl -s "https://productlane.com/api/v1/contacts?take=20" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Get Contact by ID or Email

Replace `<contact-id-or-email>` with the actual contact ID or email address:

```bash
curl -s "https://productlane.com/api/v1/contacts/<contact-id-or-email>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Create Contact

Link to a company using `companyId` (recommended), `companyName`, or `companyExternalId` — these are mutually exclusive.

Write to `/tmp/productlane_request.json`:

```json
{
  "email": "jane@acme.com",
  "name": "Jane Doe",
  "companyId": "<company-id>"
}
```

Then run:

```bash
curl -s -X POST "https://productlane.com/api/v1/contacts" --header "Authorization: Bearer $PRODUCTLANE_TOKEN" --header "Content-Type: application/json" -d @/tmp/productlane_request.json
```

### Update Contact

Write to `/tmp/productlane_request.json`:

```json
{
  "name": "Jane Smith"
}
```

Then run. Replace `<contact-id>` with the actual contact ID:

```bash
curl -s -X PATCH "https://productlane.com/api/v1/contacts/<contact-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN" --header "Content-Type: application/json" -d @/tmp/productlane_request.json
```

### Delete Contact

Replace `<contact-id>` with the actual contact ID:

```bash
curl -s -X DELETE "https://productlane.com/api/v1/contacts/<contact-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

## Threads (Feedback)

### List Threads

```bash
curl -s "https://productlane.com/api/v1/threads?take=20" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### List Threads with Filters

Filter by state (`NEW`, `PROCESSED`), issue, or project:

```bash
curl -s "https://productlane.com/api/v1/threads?state=NEW&take=50" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Get Thread by ID

Replace `<thread-id>` with the actual thread ID:

```bash
curl -s "https://productlane.com/api/v1/threads/<thread-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Create Thread

Required fields: `title`, `text`, `contactEmail`, `painLevel`.

Write to `/tmp/productlane_request.json`:

```json
{
  "title": "Feature request: Dark mode",
  "text": "<p>It would be great to have a dark mode option for the dashboard.</p>",
  "contactEmail": "jane@acme.com",
  "actorName": "Jane Doe",
  "painLevel": "MEDIUM"
}
```

**Pain level values:** `UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`

Then run:

```bash
curl -s -X POST "https://productlane.com/api/v1/threads" --header "Authorization: Bearer $PRODUCTLANE_TOKEN" --header "Content-Type: application/json" -d @/tmp/productlane_request.json
```

### Update Thread

Write to `/tmp/productlane_request.json`:

```json
{
  "title": "Feature request: Dark mode (updated)"
}
```

Then run. Replace `<thread-id>` with the actual thread ID:

```bash
curl -s -X PATCH "https://productlane.com/api/v1/threads/<thread-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN" --header "Content-Type: application/json" -d @/tmp/productlane_request.json
```

### Send Message to Thread

Send an email or Slack message to a thread. Replace `<thread-id>` with the actual thread ID:

Write to `/tmp/productlane_request.json`:

```json
{
  "text": "Thank you for your feedback! We are working on this feature."
}
```

Then run:

```bash
curl -s -X POST "https://productlane.com/api/v1/threads/<thread-id>/messages" --header "Authorization: Bearer $PRODUCTLANE_TOKEN" --header "Content-Type: application/json" -d @/tmp/productlane_request.json
```

## Changelogs

### List Changelogs

Replace `<workspace-id>` with the actual workspace ID:

```bash
curl -s "https://productlane.com/api/v1/changelogs/<workspace-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Get Changelog

Replace `<workspace-id>` and `<changelog-id>` with the actual IDs:

```bash
curl -s "https://productlane.com/api/v1/changelogs/<workspace-id>/<changelog-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Create Changelog

Write to `/tmp/productlane_request.json`:

```json
{
  "title": "March 2026 Update",
  "content": "## New Features\n\n- Dark mode support\n- Improved search\n- New API endpoints"
}
```

Then run:

```bash
curl -s -X POST "https://productlane.com/api/v1/changelogs" --header "Authorization: Bearer $PRODUCTLANE_TOKEN" --header "Content-Type: application/json" -d @/tmp/productlane_request.json
```

### Update Changelog

Write to `/tmp/productlane_request.json`:

```json
{
  "title": "March 2026 Update (Revised)",
  "content": "## New Features\n\n- Dark mode support\n- Improved search\n- New API endpoints\n- Bug fixes"
}
```

Then run. Replace `<changelog-id>` with the actual changelog ID:

```bash
curl -s -X PATCH "https://productlane.com/api/v1/changelogs/<changelog-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN" --header "Content-Type: application/json" -d @/tmp/productlane_request.json
```

### Delete Changelog

Replace `<changelog-id>` with the actual changelog ID:

```bash
curl -s -X DELETE "https://productlane.com/api/v1/changelogs/<changelog-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

## Portal / Roadmap

### List Projects

Replace `<workspace-id>` with the actual workspace ID. The workspace must have its portal published:

```bash
curl -s "https://productlane.com/api/v1/projects/<workspace-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Get Project

Replace `<workspace-id>` and `<project-id>` with the actual IDs:

```bash
curl -s "https://productlane.com/api/v1/projects/<workspace-id>/<project-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### List Issues

Replace `<workspace-id>` with the actual workspace ID:

```bash
curl -s "https://productlane.com/api/v1/issues/<workspace-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Get Issue

Replace `<workspace-id>` and `<issue-id>` with the actual IDs:

```bash
curl -s "https://productlane.com/api/v1/issues/<workspace-id>/<issue-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Upvote a Project or Issue

Write to `/tmp/productlane_request.json`:

```json
{
  "projectId": "<project-id>",
  "email": "jane@acme.com"
}
```

Then run:

```bash
curl -s -X POST "https://productlane.com/api/v1/portal/upvotes" --header "Authorization: Bearer $PRODUCTLANE_TOKEN" --header "Content-Type: application/json" -d @/tmp/productlane_request.json
```

### Get Upvotes

```bash
curl -s "https://productlane.com/api/v1/portal/upvotes?projectId=<project-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Delete Upvote

Replace `<upvote-id>` with the actual upvote ID:

```bash
curl -s -X DELETE "https://productlane.com/api/v1/portal/upvotes/<upvote-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

## Documentation

### List Articles

Replace `<workspace-id>` with the actual workspace ID:

```bash
curl -s "https://productlane.com/api/v1/docs/articles/<workspace-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Get Article

Replace `<workspace-id>` and `<article-id>` with the actual IDs:

```bash
curl -s "https://productlane.com/api/v1/docs/articles/<workspace-id>/<article-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Create Article

Requires `groupId`. Create a doc group first if needed.

Write to `/tmp/productlane_request.json`:

```json
{
  "title": "Getting Started",
  "content": "## Welcome\n\nThis guide will help you get started with our product.",
  "groupId": "<group-id>"
}
```

Then run:

```bash
curl -s -X POST "https://productlane.com/api/v1/docs/articles" --header "Authorization: Bearer $PRODUCTLANE_TOKEN" --header "Content-Type: application/json" -d @/tmp/productlane_request.json
```

### Update Article

Write to `/tmp/productlane_request.json`:

```json
{
  "title": "Getting Started (Updated)",
  "content": "## Welcome\n\nThis updated guide will help you get started."
}
```

Then run. Replace `<article-id>` with the actual article ID:

```bash
curl -s -X PATCH "https://productlane.com/api/v1/docs/articles/<article-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN" --header "Content-Type: application/json" -d @/tmp/productlane_request.json
```

### Delete Article

Replace `<article-id>` with the actual article ID:

```bash
curl -s -X DELETE "https://productlane.com/api/v1/docs/articles/<article-id>" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Create Doc Group

Write to `/tmp/productlane_request.json`:

```json
{
  "name": "User Guides"
}
```

Then run:

```bash
curl -s -X POST "https://productlane.com/api/v1/docs/groups" --header "Authorization: Bearer $PRODUCTLANE_TOKEN" --header "Content-Type: application/json" -d @/tmp/productlane_request.json
```

### Move Articles to Group

Write to `/tmp/productlane_request.json`:

```json
{
  "articleIds": ["<article-id-1>", "<article-id-2>"],
  "groupId": "<group-id>"
}
```

Then run:

```bash
curl -s -X POST "https://productlane.com/api/v1/docs/groups/move-articles" --header "Authorization: Bearer $PRODUCTLANE_TOKEN" --header "Content-Type: application/json" -d @/tmp/productlane_request.json
```

## Users

### List Members

```bash
curl -s "https://productlane.com/api/v1/users" --header "Authorization: Bearer $PRODUCTLANE_TOKEN"
```

### Invite User

Write to `/tmp/productlane_request.json`:

```json
{
  "email": "newuser@acme.com"
}
```

Then run:

```bash
curl -s -X POST "https://productlane.com/api/v1/users/invite" --header "Authorization: Bearer $PRODUCTLANE_TOKEN" --header "Content-Type: application/json" -d @/tmp/productlane_request.json
```

### Update User Role

Only admins can change roles. Valid roles: `ADMIN`, `USER`, `VIEWER`.

Write to `/tmp/productlane_request.json`:

```json
{
  "userId": "<user-id>",
  "role": "USER"
}
```

Then run:

```bash
curl -s -X PATCH "https://productlane.com/api/v1/users/role" --header "Authorization: Bearer $PRODUCTLANE_TOKEN" --header "Content-Type: application/json" -d @/tmp/productlane_request.json
```

## Guidelines

1. **Base URL**: All endpoints use `https://productlane.com/api/v1/`
2. **Pagination**: Use `skip` and `take` query parameters for paginated endpoints (default `take` is 10)
3. **Markdown support**: Changelog and documentation article `content` fields support markdown format
4. **HTML support**: Thread `text` field supports HTML content
5. **Thread fields**: Use `contactEmail` (not `email`) and uppercase `painLevel` values (`UNKNOWN`, `LOW`, `MEDIUM`, `HIGH`)
6. **Doc articles**: `groupId` is required when creating articles — create a doc group first
7. **Company linking**: When creating contacts, use exactly one of `companyId` (recommended), `companyName`, or `companyExternalId`
8. **Public endpoints**: Workspace, portal issues/projects, and published changelogs/articles can be accessed without authentication
9. **Security**: Never expose API keys in logs or client-side code

## API Reference

- Documentation: https://productlane.mintlify.dev/docs/api-reference
- Dashboard: https://productlane.com
- API settings: https://productlane.com/settings/integrations/api

More from vm0-ai/vm0-skills

SkillDescription
account-reconciliationPerform account reconciliations comparing general ledger balances against subledgers, bank statements, or external records. Use for bank reconciliation, GL-to-subledger reconciliation, intercompany reconciliation, balance sheet reconciliation, reconciling item analysis, outstanding item aging, or clearing open items.
agentphoneBuild AI phone agents with AgentPhone API. Use when the user wants to make phone calls, send/receive SMS, manage phone numbers, create voice agents, set up webhooks, or check usage — anything related to telephony, phone numbers, or voice AI.
ahrefsAhrefs SEO API for backlink and keyword analysis. Use when user mentions
amplitudeAmplitude product analytics API. Use when user mentions "Amplitude",
analysis-qaQuality-check a data analysis before sharing — verify joins, aggregations, denominators, time ranges, and metric definitions. Detect pitfalls like survivorship bias, average-of-averages, join explosion, timezone mismatches, incomplete periods, and selection bias. Includes documentation templates for reproducible analyses.
anthropic-managed-agentsAnthropic Managed Agents API for programmatically creating, running, and streaming AI agents on Anthropic's cloud infrastructure. Use when the user mentions "Managed Agents", "Anthropic agent sessions", or needs to create/run/stream an Anthropic agent with tool use (bash, git, web), attach GitHub repositories, or inject secrets via Vault. Do NOT use for standard Claude Messages API — use the Claude API skill instead.
apifyApify web scraping platform. Use when user mentions "scrape website",
asanaAsana API for tasks and projects. Use when user mentions "Asana", "asana.com",
atlassianAtlassian API for Confluence and Jira. Use when user mentions "Confluence
attioAttio REST API for AI-native CRM operations — manage companies, people, deals, and custom objects, plus notes, tasks, lists, and comments. Use when the user mentions "Attio", "CRM record", "create company", "add person", "list entry", "CRM note", or "CRM task".