Skip to content

Submitting Feedback via API

Submit feedback programmatically from your server, CI pipeline, or any backend that can make HTTP requests.


When to Use This

  • Your app has its own feedback UI and you want to forward submissions to Canviq
  • You're migrating historical feedback from another tool
  • You want to create submissions from automated monitoring (e.g., error thresholds trigger a problem report)

For user-facing feedback, consider the iframe embed first — it requires zero server code.


Prerequisites

  • An org API key with the submissions:write scope — see Authentication
  • Your category_id values if you want to tag submissions (fetch them from GET /api/organizations/{id}/categories)

Create a Submission

POST /api/submissions
Authorization: Bearer pk_org_live_...
Content-Type: application/json

Request Body

Field Type Required Description
title string Yes Short title (5–200 chars)
description string Yes Full description (20–5000 chars)
type "idea" | "problem" Yes Feedback category
category_id UUID No Assign to a board category
author_email string No Email for attribution and notifications
author_name string No Display name for the author
source string No Tag by origin (e.g. "ios-app", "android", "web")

Example

curl -X POST https://canviq.app/api/submissions \
  -H "Authorization: Bearer $CANVIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Offline mode support",
    "description": "When I lose connectivity, I want to be able to view my saved items and queue changes for sync.",
    "type": "idea",
    "category_id": "3f6a1b2c-...",
    "author_email": "[email protected]",
    "author_name": "Jane Smith",
    "source": "ios-app"
  }'
async function submitFeedback(params: {
  title: string
  description: string
  type: 'idea' | 'problem'
  authorEmail?: string
  authorName?: string
  categoryId?: string
  source?: string
}) {
  const response = await fetch('https://canviq.app/api/submissions', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.CANVIQ_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      title: params.title,
      description: params.description,
      type: params.type,
      category_id: params.categoryId,
      author_email: params.authorEmail,
      author_name: params.authorName,
      source: params.source,
    }),
  })

  if (!response.ok) {
    const err = await response.json()
    throw new Error(`Canviq error ${response.status}: ${err.error}`)
  }

  return response.json() as Promise<{ id: string; url: string }>
}
import httpx, os
from typing import Optional

def submit_feedback(
    title: str,
    description: str,
    type: str,  # 'idea' or 'problem'
    author_email: Optional[str] = None,
    author_name: Optional[str] = None,
    category_id: Optional[str] = None,
    source: Optional[str] = None,
) -> dict:
    resp = httpx.post(
        'https://canviq.app/api/submissions',
        headers={'Authorization': f'Bearer {os.environ["CANVIQ_API_KEY"]}'},
        json={
            'title': title,
            'description': description,
            'type': type,
            'author_email': author_email,
            'author_name': author_name,
            'category_id': category_id,
            'source': source,
        },
    )
    resp.raise_for_status()
    return resp.json()

Response

{
  "id": "9d3a1f2e-...",
  "url": "https://acme.canviq.app/en/submissions/9d3a1f2e-..."
}

Bulk Import

For migrating large volumes of historical feedback, contact [email protected] for elevated rate limits and a bulk import endpoint.

The standard endpoint accepts up to 100 requests per minute per API key.


Rate Limits

See Rate Limits for the full table. On the standard plan:

  • 100 submissions/min per API key
  • Responses include X-RateLimit-Remaining headers

If you exceed the limit, you'll receive a 429 response. Back off exponentially and retry.


Error Handling

See Error Reference for the full list. Common cases:

Error Code What to do
Missing required field validation_error (400) Check the field in the error message
Invalid API key unauthorized (401) Verify CANVIQ_API_KEY is set correctly
Wrong scope forbidden (403) Regenerate key with submissions:write
Rate limited rate_limited (429) Back off and retry; check headers
Plan limit reached plan_limit_reached (402) Upgrade or contact support