Skip to content

Submissions API

!!! info "TL;DR" CRUD operations for feedback submissions. List, search, filter, create, update. Public read, authenticated write.

List Submissions

Get all submissions with optional filtering and sorting.

GET /api/submissions

Authentication: Optional (public endpoint)

Query Parameters:

Parameter Type Description
page number Page number (default: 1)
limit number Items per page (default: 50, max: 100)
status enum Filter by status
type enum idea or problem
category string Category ID or slug
tag string Tag slug
author string Author user ID
q string Full-text search query
sort string Sort field (created_at, votes, comments)
order string asc or desc (default: desc)

Example Request:

curl "https://canviq.app/api/submissions?status=planned&sort=votes&order=desc"

Example Response:

{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "title": "Dark mode support",
      "description": "Add a dark mode option to reduce eye strain",
      "type": "idea",
      "status": "planned",
      "vote_count": 42,
      "comment_count": 8,
      "author_id": "uuid",
      "category_id": "uuid",
      "tags": ["ui", "accessibility"],
      "created_at": "2026-01-15T10:30:00Z",
      "updated_at": "2026-02-01T14:20:00Z"
    }
  ],
  "meta": {
    "page": 1,
    "limit": 50,
    "total": 123,
    "total_pages": 3,
    "has_next": true,
    "has_prev": false
  }
}

Get Submission

Get a single submission by ID with expanded relations.

GET /api/submissions/:id

Authentication: Optional

Query Parameters:

Parameter Type Description
expand string Comma-separated list: author, category, tags, comments

Example Request:

curl "https://canviq.app/api/submissions/550e8400-e29b-41d4-a716-446655440000?expand=author,category"

Example Response:

{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "title": "Dark mode support",
    "description": "Add a dark mode option to reduce eye strain...",
    "type": "idea",
    "status": "planned",
    "vote_count": 42,
    "comment_count": 8,
    "author": {
      "id": "uuid",
      "name": "Jane Doe",
      "avatar": "https://cdn.canviq.app/avatars/...",
      "is_team_member": false
    },
    "category": {
      "id": "uuid",
      "name": "Feature Requests",
      "slug": "feature-requests",
      "color": "blue"
    },
    "tags": [
      { "name": "UI", "slug": "ui" },
      { "name": "Accessibility", "slug": "accessibility" }
    ],
    "github_issue_url": null,
    "is_following": false,
    "user_vote": null,
    "created_at": "2026-01-15T10:30:00Z",
    "updated_at": "2026-02-01T14:20:00Z"
  }
}

Create Submission

Create a new feedback submission.

POST /api/submissions

Authentication: Required

Request Body:

{
  "title": "Dark mode support",
  "description": "Add a dark mode option to reduce eye strain during evening use. Many modern apps offer this feature.",
  "type": "idea",
  "category_id": "550e8400-e29b-41d4-a716-446655440000"
}

Fields:

Field Type Required Description
title string Yes 5-200 characters
description string Yes 20-5000 characters
type enum Yes idea or problem
category_id UUID No Category to assign

Example Request:

curl -X POST https://canviq.app/api/submissions \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Dark mode support",
    "description": "Add a dark mode option...",
    "type": "idea",
    "category_id": "550e8400-e29b-41d4-a716-446655440000"
  }'

Example Response:

{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440001",
    "title": "Dark mode support",
    "status": "open",
    "vote_count": 1,
    "url": "https://canviq.app/submissions/550e8400-e29b-41d4-a716-446655440001"
  }
}

The submitting user automatically votes for their own submission and follows it for updates.

Update Submission

Update an existing submission (author only, or admin).

PATCH /api/submissions/:id

Authentication: Required (must be author or admin)

Request Body:

{
  "title": "Dark mode support for mobile app",
  "description": "Updated description..."
}

Updatable Fields:

Field Type Description
title string Updated title
description string Updated description
category_id UUID Change category

Example Request:

curl -X PATCH https://canviq.app/api/submissions/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"title": "Dark mode support for mobile app"}'

Search Submissions

Full-text search across titles and descriptions.

GET /api/submissions/search

Authentication: Optional

Query Parameters:

Parameter Type Description
q string Search query (required)
page number Page number
limit number Items per page
status enum Filter by status
type enum Filter by type

Example Request:

curl "https://canviq.app/api/submissions/search?q=dark+mode&status=planned"

Example Response:

{
  "data": [
    {
      "id": "...",
      "title": "Dark mode support",
      "description": "...",
      "relevance": 0.87,
      "highlight": {
        "title": "<mark>Dark mode</mark> support",
        "description": "Add a <mark>dark mode</mark> option..."
      }
    }
  ],
  "meta": {
    "query": "dark mode",
    "total": 3
  }
}

!!! warning "XSS Warning" The highlight field contains raw HTML <mark> tags. Always sanitize these values before rendering in the browser to prevent cross-site scripting (XSS) attacks. Use a library like DOMPurify or sanitize-html.

Check for Duplicates

Find similar submissions before creating a new one.

POST /api/submissions/check-duplicates

Authentication: Optional

Rate Limit: 30 requests per minute (unauthenticated), 100 per minute (authenticated). This endpoint can be used for content enumeration — rate limiting is enforced.

Request Body:

{
  "title": "Dark mode support",
  "description": "Add a dark mode option..."
}

Example Response:

{
  "data": {
    "has_duplicates": true,
    "similar": [
      {
        "id": "...",
        "title": "Dark theme for app",
        "similarity": 0.92,
        "vote_count": 42,
        "status": "planned"
      },
      {
        "id": "...",
        "title": "Night mode",
        "similarity": 0.78,
        "vote_count": 15,
        "status": "open"
      }
    ]
  }
}

Use this before calling POST /api/submissions to prevent duplicate submissions.

What's Next