Skip to main content

Collect feedback from Python

Accept feedback from inside your product, have each message classified, and forward it to wherever your team already works. No inbox to babysit.

Keys

Browser calls use a publishable key (nv_pub_live_…), which is safe to ship. Reading and admin calls use a secret key (nv_live_…) on your server only. Create both under Dashboard → API keys.

Publishable key pasted into the page that embeds the form
NORDVA_SECRET_KEY=nv_live_…

01Server: Python

feedback-submit.py

import os
import httpx

res = httpx.post(
    "https://api.nordva.dev/v1/feedback",
    headers={"Authorization": f"Bearer {os.environ['NORDVA_SECRET_KEY']}"},
    json={"feedback_text": text, "user_id": user_id, "page_url": page_url},
)
if res.status_code >= 400:
    err = res.json()["error"]
    raise RuntimeError(f"{err['code']}: {err['message']}")
data = res.json()["data"]
print(data["category"], data["sentiment"])

02Server: list open bugs, Python

feedback-list.py

import os
import httpx

res = httpx.get(
    "https://api.nordva.dev/v1/feedback?category=bug&status=open&limit=20",
    headers={"Authorization": f"Bearer {os.environ['NORDVA_SECRET_KEY']}"},
)
if res.status_code >= 400:
    err = res.json()["error"]
    raise RuntimeError(f"{err['code']}: {err['message']}")
data = res.json()["data"]
for item in data:
    print(item["id"], item["category"], item["feedback_text"][:80])

03Zero-code alternative: hosted widget

any HTML page

<script src="https://cdn.nordva.dev/v1/feedback.js"
  data-key="nv_pub_live_…"
  data-position="bottom-right"
  data-accent="#A8552E"
  data-user-id="user_123"></script>

04Verify from a terminal

curl -s "https://api.nordva.dev/v1/feedback?limit=5" \
  -H "Authorization: Bearer nv_live_…" | jq '.data[] | {category, sentiment, feedback_text}'

Behaviour worth knowing

  • Every response is { data, error, meta }. On failure error.code is a stable string such as VALIDATION_ERROR, PLAN_LIMIT_REACHED or RATE_LIMITED, with a remediation message.
  • POST and PATCH requests accept an Idempotency-Key header; the same key with the same body returns the original response for 24 hours.
  • Rate limits per key: 30 requests a minute on Free, 120 on Indie, 500 on Builder. A 429 carries Retry-After.
  • Browser calls with a publishable key must come from an origin registered on the project, otherwise the API answers ORIGIN_NOT_ALLOWED.