Skip to main content

Error Reference

Every API error returns a consistent JSON structure with a machine-readable code, a human-readable message, and a doc_url pointing back here. This page covers every error you might encounter, why it happens, and how to fix it.

Error response shape
{
  "success": false,
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_missing",
    "message": "The 'title' field is required.",
    "param": "title",
    "doc_url": "https://cstar.help/developers/errors#parameter_missing",
    "request_id": "req_abc123"
  }
}

Error Types

Every error falls into one of five top-level types. The type field tells you the category, while code gives you the specific error.

authentication_error

API key is missing, invalid, expired, or doesn't have the right permissions.

invalid_request_error

The request has invalid parameters, missing fields, bad JSON, or conflicts.

not_found_error

The resource you're trying to access doesn't exist.

rate_limit_error

You've exceeded the rate limit for your API key type.

api_error

Something went wrong on our end. These are rare and usually transient.

Authentication Errors

authentication_required 401

Missing or invalid Authorization header.

Why this happens

  • You didn't include an Authorization header in your request
  • The header format is wrong (should be Bearer sk_live_xxx)
  • You accidentally included extra whitespace or newlines in the header

How to fix it

# Correct format
curl -H "Authorization: Bearer sk_live_your_key_here" \
  https://www.cstar.help/api/v1/teams/{teamId}/tickets
With the SDK (handles auth automatically)
import { CStarClient } from '@cstar.help/js';

const cstar = new CStarClient({ apiKey: 'sk_live_your_key_here' });
// Auth header is set automatically on every request
invalid_api_key 401

The API key provided is invalid or has been revoked.

Why this happens

  • The key was revoked from the dashboard or via cstar keys revoke
  • You're using a key from a different team or environment
  • The key was copied incorrectly (truncated or extra characters)

How to fix it

# Check your current key status
cstar status

# List all valid keys
cstar keys list

# Create a new key if needed
cstar keys create --name "My App"
invalid_key_format 401

Invalid API key format.

Why this happens

  • The key doesn't start with a recognized prefix (sk_live_, sk_test_, pk_live_, pk_test_)
  • You might be passing an OAuth token or JWT instead of an API key

Valid key formats

sk_live_*Secret key — production, full access
sk_test_*Secret key — test mode, full access
pk_live_*Publishable key — production, read-only
pk_test_*Publishable key — test mode, read-only
key_expired 401

This API key has expired.

Why this happens

  • The key was created with an expiration date that has passed
  • Your team's security policy may auto-expire keys after a set period

How to fix it

Generate a new key from your dashboard or CLI:

cstar keys create --name 'Replacement Key'
insufficient_permissions 403

Your API key does not have permission for this operation.

Why this happens

  • The key was created with restricted scopes that don't include this resource
  • Your team role doesn't grant access to this operation

How to fix it

Check your key's permissions in the dashboard, or create a new key with the required scopes.

publishable_key_write 403

Publishable keys are read-only.

Why this happens

  • You're using a pk_live_ or pk_test_ key to create, update, or delete a resource
  • Publishable keys are designed for client-side use and only allow read operations

How to fix it

Use a secret key (sk_live_*) for write operations. Keep secret keys server-side — never expose them in frontend code.

Server-side: use secret key for writes
// Server-side only — never expose sk_ keys in the browser
const cstar = new CStarClient({ apiKey: 'sk_live_your_secret_key' });

// This works with a secret key
await cstar.tickets.create({ title: 'New ticket' });
team_access_denied 403

Your API key does not have access to this team.

Why this happens

  • The teamId in the URL doesn't match the team the API key belongs to
  • You may have multiple teams and are using a key from the wrong one

How to fix it

# Check which team your key belongs to
cstar status

# The teamId in your URL must match
# https://www.cstar.help/api/v1/teams/{THIS_TEAM_ID}/tickets

Invalid Request Errors

parameter_missing 400

A required parameter is missing.

Why this happens

  • A required field was not included in the request body
  • The field name is misspelled (e.g., tittle instead of title)
  • You sent the parameter as a query param instead of in the JSON body (or vice versa)

How to fix it

Check the param field in the error response — it tells you exactly which parameter is missing.

Error response tells you the missing field
{
  "error": {
    "code": "parameter_missing",
    "message": "The 'title' field is required.",
    "param": "title"
  }
}
Fix: include the required field
// Before (missing title)
await cstar.tickets.create({ priority: 'high' });

// After (title included)
await cstar.tickets.create({ title: 'Help needed', priority: 'high' });
parameter_invalid 400

A parameter has an invalid value.

Why this happens

  • A field value doesn't match the expected type (e.g., string where number expected)
  • An enum field has an invalid value (e.g., status: "done" when valid values are new, open, pending, resolved, closed)
  • A number is out of range (e.g., pageSize: 500 when max is 100)

How to fix it

Check the param field and refer to the API reference for valid values.

Common fix: use valid enum values
// Before (invalid priority value)
await cstar.tickets.create({ title: 'Help', priority: 'super-urgent' });

// After (valid values: low, normal, high, urgent)
await cstar.tickets.create({ title: 'Help', priority: 'urgent' });
invalid_json 400

The request body contains invalid JSON.

Why this happens

  • The JSON has a syntax error (missing comma, bracket, or quote)
  • You sent form-encoded data instead of JSON
  • The Content-Type header is missing or wrong

How to fix it

Make sure Content-Type is set and JSON is valid
curl -X POST \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"title": "Help needed"}' \
  https://www.cstar.help/api/v1/teams/{teamId}/tickets

Using the SDK? You never need to worry about this — the SDK handles JSON serialization and Content-Type headers automatically.

invalid_id_format 400

The ID format is invalid.

Why this happens

  • The ID in the URL path isn't a valid UUID or prefixed ID
  • You may have included extra characters or truncated the ID

Valid ID formats

# UUID format
550e8400-e29b-41d4-a716-446655440000

# Prefixed format (resource-specific)
tkt_550e8400e29b41d4a716446655440000  (tickets)
cus_7c9e667974254de0944be07fc1f90ae7  (customers)
art_a1b2c3d4e5f6789012345678abcdef00  (articles)
whk_d4e5f6789012345678abcdef00a1b2c3  (webhooks)
resource_conflict 409

A resource with this identifier already exists.

Why this happens

  • You're trying to create a resource with a unique field that already exists (e.g., duplicate email for a customer)
  • A webhook with the same URL and event combination already exists

How to fix it

Use a unique value, or update the existing resource with a PATCH request instead of creating a new one.

Update existing instead of creating duplicate
// Instead of creating a duplicate customer:
// await cstar.customers.create({ email: 'jane@example.com' });

// Find and update the existing one:
const { data } = await cstar.customers.list({ search: 'jane@example.com' });
if (data.length > 0) {
  await cstar.customers.update(data[0].id, { name: 'Jane Doe' });
}

Not Found Errors

resource_not_found 404

The requested resource was not found.

Why this happens

  • The resource ID doesn't exist (it may have been deleted)
  • The ID is correct but belongs to a different team
  • You're using a test-mode key but the resource was created in live mode (or vice versa)

How to fix it

Verify the resource exists before operating on it
try {
  const { data } = await cstar.tickets.get('tkt_abc123');
  console.log(data);
} catch (err) {
  if (err.code === 'resource_not_found') {
    console.log('Ticket not found — it may have been deleted');
  }
}

Make sure you're using the right environment. Resources created with sk_test_ keys are only visible with test keys, and vice versa.

Rate Limit Errors

rate_limit_exceeded 429

Too many requests.

Current limits

sk_live_* / sk_test_*1,000 requests per hour
pk_live_* / pk_test_*100 requests per hour

Rate limit headers

Every response includes these headers so you can track your usage:

X-RateLimit-LimitMax requests per window
X-RateLimit-RemainingRequests remaining
X-RateLimit-ResetUnix timestamp when window resets
Retry-AfterSeconds to wait (only on 429)

How to fix it

Implement exponential backoff
async function withRetry(fn, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (err) {
      if (err.code === 'rate_limit_exceeded' && i < maxRetries - 1) {
        const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s
        console.log(`Rate limited. Retrying in ${delay}ms...`);
        await new Promise(r => setTimeout(r, delay));
      } else {
        throw err;
      }
    }
  }
}

Webhook deliveries do NOT count against your rate limit. You can receive unlimited webhooks without impacting your API quota.

Server Errors

internal_error 500

An unexpected error occurred on our end.

Why this happens

  • This is a bug on our side, not something you did wrong
  • These are rare and usually transient

What to do

  • Retry the request — most server errors are transient
  • Include the request_id from the error response when contacting support
  • If it persists, email support@cstar.help with the request ID
database_error 500

A database error occurred while processing your request.

What to do

  • Wait a few seconds and retry — this is usually a transient issue
  • If it keeps happening, the request_id will help us debug it

Handling Errors in Code

The cStar SDKs throw typed errors that you can catch and handle by code.

SDK error handling
import { CStarClient, CStarError } from '@cstar.help/js';

const cstar = new CStarClient({ apiKey: 'sk_live_xxx' });

try {
  await cstar.tickets.create({ priority: 'high' }); // missing title
} catch (err) {
  if (err instanceof CStarError) {
    switch (err.code) {
      case 'parameter_missing':
        console.log(`Missing field: ${err.param}`);
        break;
      case 'rate_limit_exceeded':
        console.log(`Retry after ${err.retryAfter} seconds`);
        break;
      case 'authentication_required':
        console.log('Check your API key');
        break;
      default:
        console.log(`API error: ${err.message}`);
    }
  }
}