Skip to main content
POST
/
v1
/
feedback
Submit Feedback
curl --request POST \
  --url https://api.signa.so/v1/feedback \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "type": "<string>",
  "message": "<string>",
  "resource_id": "<string>",
  "request_id": "<string>",
  "field": "<string>",
  "expected_value": "<string>",
  "metadata": {}
}
'
import requests

url = "https://api.signa.so/v1/feedback"

payload = {
"type": "<string>",
"message": "<string>",
"resource_id": "<string>",
"request_id": "<string>",
"field": "<string>",
"expected_value": "<string>",
"metadata": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
type: '<string>',
message: '<string>',
resource_id: '<string>',
request_id: '<string>',
field: '<string>',
expected_value: '<string>',
metadata: {}
})
};

fetch('https://api.signa.so/v1/feedback', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.signa.so/v1/feedback",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'type' => '<string>',
'message' => '<string>',
'resource_id' => '<string>',
'request_id' => '<string>',
'field' => '<string>',
'expected_value' => '<string>',
'metadata' => [

]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"strings"
"net/http"
"io"
)

func main() {

url := "https://api.signa.so/v1/feedback"

payload := strings.NewReader("{\n \"type\": \"<string>\",\n \"message\": \"<string>\",\n \"resource_id\": \"<string>\",\n \"request_id\": \"<string>\",\n \"field\": \"<string>\",\n \"expected_value\": \"<string>\",\n \"metadata\": {}\n}")

req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://api.signa.so/v1/feedback")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"type\": \"<string>\",\n \"message\": \"<string>\",\n \"resource_id\": \"<string>\",\n \"request_id\": \"<string>\",\n \"field\": \"<string>\",\n \"expected_value\": \"<string>\",\n \"metadata\": {}\n}")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.signa.so/v1/feedback")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"type\": \"<string>\",\n \"message\": \"<string>\",\n \"resource_id\": \"<string>\",\n \"request_id\": \"<string>\",\n \"field\": \"<string>\",\n \"expected_value\": \"<string>\",\n \"metadata\": {}\n}"

response = http.request(request)
puts response.read_body
{
  "id": "fbk_550e8400-e29b-41d4-a716-446655440000",
  "object": "feedback",
  "api_key_id": "key_1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
  "type": "data_issue",
  "status": "open",
  "message": "The registered owner is out of date; this mark was assigned last year.",
  "resource_id": "tm_9f8e7d6c-5b4a-3210-fedc-ba9876543210",
  "request_ref": "req_01kpjabcdefghijkmnpqrstvwx",
  "field": "owner.name",
  "expected_value": "Acme Holdings LLC",
  "context": {
    "request": {
      "route": "/v1/trademarks/{id}",
      "method": "GET",
      "status_code": 200,
      "error_type": null,
      "error_detail": null,
      "duration_ms": 12,
      "occurred_at": "2026-07-10T12:34:56.000Z"
    },
    "resource": {
      "found": true,
      "resource_type": "trademark",
      "office": "uspto",
      "jurisdiction": "US",
      "version": 3,
      "status_primary": "active",
      "source_updated_at": "2026-07-01T00:00:00.000Z",
      "updated_at": "2026-07-02T08:00:00.000Z"
    }
  },
  "resolution_note": null,
  "metadata": {},
  "created_at": "2026-07-10T12:40:00.000Z",
  "updated_at": "2026-07-10T12:40:00.000Z",
  "resolved_at": null,
  "request_id": "req_cW8oQ3rT"
}

Overview

Submit structured feedback about the Signa API or its data. This is the programmatic reporting channel: use it to flag an inaccurate record, report a server error you hit, or request a capability. It is designed for both humans and AI agents acting on your behalf. Every submission is stored in your organization, posted to the Signa team for triage, and readable back so you can watch it move through its status lifecycle. Feedback is never billed (0 units) and runs on generous rate limits, so reporting a problem never costs you anything. Any valid API key may submit feedback for its organization; no special scope is required. An Idempotency-Key header is required (the standard mutating-request rule), so a retried submission never creates a duplicate.

Feedback types

The required type discriminator routes and categorizes the report:
typeUse it for
data_issueA record disagrees with the official registry (wrong owner name, stale status, missing field). Pair with resource_id, field, and expected_value to make it actionable.
bugThe API behaved incorrectly (an unexpected error, a wrong response shape). Attach request_id so we see exactly what you saw.
feature_requestA capability you want that does not exist yet.
otherAnything that does not fit the above. A message alone is always valid.

Request Body

type
string
required
One of data_issue, bug, feature_request, other.
message
string
required
Free-form report body (1 to 5000 characters).
resource_id
string
Public ID of any referenced entity (tm_..., own_..., att_..., firm_..., prc_...). At submit time the server snapshots the record’s current state into context.resource.
request_id
string
The request_id of the API request where you observed the problem (req_..., or a client-supplied x-request-id; up to 64 URL-safe characters). At submit time the server snapshots the matching request log into context.request.
field
string
For data issues: which field is wrong (for example owner.name). Up to 255 characters.
expected_value
string
For data issues: what the value should be. Up to 5000 characters.
metadata
object
Optional string-to-string map for your own tags (max 50 keys).

Submit-time enrichment

When you reference a request_id or a resource_id, Signa captures an investigation snapshot into the read-only context object at submit time. This matters because request logs are dropped after roughly four months while feedback lives indefinitely, and because a record can be overwritten by a later sync. The snapshot preserves what you saw. Enrichment never rejects a submission. An unknown, foreign, or non-existent reference is recorded as null or found: false rather than returning an error. context.request is present when you sent request_id:
  • An object { route, method, status_code, error_type, error_detail, duration_ms, occurred_at } when the request is found within your organization.
  • null when the request id is unknown or belongs to another organization (no cross-org leakage).
context.resource is present when you sent resource_id:
  • { found: true, resource_type, office, jurisdiction, version, status_primary, source_updated_at, updated_at } when the record exists (with null where a given entity type lacks a field).
  • { found: false, resource_type } when the record does not exist.
A context key is simply absent when the corresponding reference was not provided or the snapshot could not be captured.

Response

Returns the created feedback object with HTTP 201.
id
string
The feedback identifier (fbk_...).
object
string
Always feedback.
api_key_id
string | null
Public ID (key_...) of the API key that filed this report, for per-key attribution within your org. null if unattributed.
type
string
The submitted type (data_issue, bug, feature_request, other).
status
string
Lifecycle status: open on creation, then acknowledged or resolved.
message
string
The report body you submitted.
resource_id
string | null
The referenced entity’s public ID, echoed back, or null.
request_ref
string | null
The request_id you referenced, echoed verbatim. Named request_ref because the envelope reserves the top-level request_id for this API call.
field
string | null
The field you flagged, or null.
expected_value
string | null
The value you expected, or null.
context
object
Server-built investigation snapshots (context.request, context.resource). Read-only, never client-supplied. See Submit-time enrichment.
resolution_note
string | null
The Signa team’s note when the report is resolved, or null.
metadata
object
Your string-to-string metadata map.
created_at
string
ISO timestamp when the report was submitted.
updated_at
string
ISO timestamp of the last status change.
resolved_at
string | null
ISO timestamp when the report was resolved, or null.
{
  "id": "fbk_550e8400-e29b-41d4-a716-446655440000",
  "object": "feedback",
  "api_key_id": "key_1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
  "type": "data_issue",
  "status": "open",
  "message": "The registered owner is out of date; this mark was assigned last year.",
  "resource_id": "tm_9f8e7d6c-5b4a-3210-fedc-ba9876543210",
  "request_ref": "req_01kpjabcdefghijkmnpqrstvwx",
  "field": "owner.name",
  "expected_value": "Acme Holdings LLC",
  "context": {
    "request": {
      "route": "/v1/trademarks/{id}",
      "method": "GET",
      "status_code": 200,
      "error_type": null,
      "error_detail": null,
      "duration_ms": 12,
      "occurred_at": "2026-07-10T12:34:56.000Z"
    },
    "resource": {
      "found": true,
      "resource_type": "trademark",
      "office": "uspto",
      "jurisdiction": "US",
      "version": 3,
      "status_primary": "active",
      "source_updated_at": "2026-07-01T00:00:00.000Z",
      "updated_at": "2026-07-02T08:00:00.000Z"
    }
  },
  "resolution_note": null,
  "metadata": {},
  "created_at": "2026-07-10T12:40:00.000Z",
  "updated_at": "2026-07-10T12:40:00.000Z",
  "resolved_at": null,
  "request_id": "req_cW8oQ3rT"
}

Code Examples

curl -X POST "https://api.signa.so/v1/feedback" \
  -H "Authorization: Bearer sig_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: data-issue-tm-9f8e7d6c-001" \
  -d '{
    "type": "data_issue",
    "message": "The registered owner is out of date; this mark was assigned last year.",
    "resource_id": "tm_9f8e7d6c-5b4a-3210-fedc-ba9876543210",
    "field": "owner.name",
    "expected_value": "Acme Holdings LLC"
  }'
import { Signa } from "@signa-so/sdk";

const signa = new Signa({ api_key: process.env.SIGNA_API_KEY });

const feedback = await signa.feedback.create({
  type: "data_issue",
  message: "The registered owner is out of date; this mark was assigned last year.",
  resource_id: "tm_9f8e7d6c-5b4a-3210-fedc-ba9876543210",
  field: "owner.name",
  expected_value: "Acme Holdings LLC",
});

console.log(feedback.id, feedback.status); // fbk_...  open

Errors

StatusTypeDescription
400validation_errorMissing type/message, message out of range, or a malformed resource_id/request_id
401unauthorizedMissing or invalid API key
409conflictIdempotency-Key reused with a different body
429rate_limitedToo many requests