{issued}

API Reference

Complete reference for the Issued API. All endpoints use JSON for requests and responses.

Authentication

API Authentication Methods
The Issued API uses different authentication methods depending on the endpoint and use case.

Project API Keys (Form Submissions)

Used for form submissions and public-facing endpoints. Generated per project.

POST
/api/submissions
Submit a form with API key authentication

Headers

Authorization: Bearer issued_abc123def456
Content-Type: application/json

Request Body

{
  "projectId": "issued_abc123def456",
  "fields": {
    "subject": {
      "visible": true,
      "required": true
    },
    "description": {
      "visible": true,
      "required": true
    }
  }
}

User Session (Dashboard APIs)

Used for project management and dashboard operations. Requires GitHub OAuth login.

GET
/api/projects
List projects (requires user session)

Webhook Signature Verification

Incoming webhooks from GitHub and email providers are verified using signatures.

// GitHub webhook signature verification
const signature = req.headers['x-hub-signature-256'];
const payload = JSON.stringify(req.body);
const expectedSignature = crypto
  .createHmac('sha256', process.env.GITHUB_WEBHOOK_SECRET)
  .update(payload)
  .digest('hex');

Form Submissions

POST /api/submissions
Submit a support form with embed-level field configuration. This is the core endpoint for all form submissions.
POST
/api/submissions
Basic form submission with visible fields

Request Body

{
  "projectId": "issued_abc123def456",
  "fields": {
    "subject": {
      "visible": true,
      "required": true
    },
    "description": {
      "visible": true,
      "required": true
    },
    "email": {
      "visible": true,
      "required": false
    }
  }
}

Field Configuration Reference

PropertyTypeDescription
visiblebooleanWhether field appears in the form UI
requiredbooleanWhether visible fields must be completed
valueanyPre-populated value (works for visible and hidden fields)

Standard Fields

Form Fields

  • subject - Issue title (max 200 chars)
  • description - Issue description (max 5000 chars)
  • email - User email for notifications
  • name - User display name

GitHub Fields

  • labels - Comma-separated GitHub labels
  • assignees - Comma-separated GitHub usernames
  • milestone - GitHub milestone number

Project Management

GET /api/projects
List all projects for the authenticated user with optional filtering and pagination.
GET
/api/projects?page=1&limit=10&search=my-app
List projects with pagination and search
POST /api/projects
Create a new project and link it to a GitHub repository or Linear team.
POST
/api/projects
Create a new project with security configuration

Request Body

{
  "name": "E-commerce Support",
  "githubRepo": "ecommerce-app",
  "githubOwner": "mycompany",
  "notificationPreferences": {
    "email": true,
    "emailAddress": "support@mycompany.com",
    "webhook": true,
    "webhookUrl": "https://mycompany.com/webhooks/issued",
    "slack": false
  },
  "whitelistedDomains": [
    "mycompany.com",
    "*.staging.mycompany.com",
    "localhost:3000"
  ],
  "whitelistedBundleIds": [
    "com.mycompany.ecommerce",
    "com.mycompany.ecommerce.staging"
  ],
  "defaultLabels": [
    "customer-support",
    "auto-created"
  ],
  "defaultAssignees": [
    "support-team"
  ]
}
GET /api/projects/{id}
Get detailed information about a specific project.
GET
/api/projects/550e8400-e29b-41d4-a716-446655440000
Get project details
PUT /api/projects/{id}
Update project configuration including security settings and notification preferences.
PUT
/api/projects/550e8400-e29b-41d4-a716-446655440000
Update project configuration

Request Body

{
  "name": "Updated App Support",
  "notificationPreferences": {
    "email": true,
    "emailAddress": "newsupport@mycompany.com",
    "webhook": true,
    "webhookUrl": "https://api.mycompany.com/webhooks/issued",
    "slack": true,
    "slackWebhookUrl": "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"
  },
  "whitelistedDomains": [
    "myapp.com",
    "*.staging.myapp.com",
    "*.preview.myapp.com"
  ],
  "whitelistedBundleIds": [
    "com.mycompany.myapp",
    "com.mycompany.myapp.beta"
  ],
  "defaultLabels": [
    "customer-reported",
    "needs-triage"
  ],
  "defaultAssignees": [
    "support-team",
    "engineering-lead"
  ]
}

Webhooks

POST /api/webhooks/github
Handles GitHub webhook events, particularly issue comment notifications.
POST
/api/webhooks/github
GitHub issue comment webhook

Headers

X-GitHub-Event: issue_comment
X-Hub-Signature-256: sha256=...
Content-Type: application/json

Request Body

{
  "action": "created",
  "issue": {
    "id": 1,
    "number": 42,
    "title": "Support Request: Cannot login to account",
    "body": "**Email**: customer@example.com\n**Name**: Jane Smith\n**Description**: I'm unable to login to my account...",
    "state": "open",
    "html_url": "https://github.com/mycompany/myapp/issues/42"
  },
  "comment": {
    "id": 123456789,
    "body": "Hi Jane, thanks for reaching out. Can you please try clearing your browser cache and cookies?",
    "user": {
      "login": "support-team",
      "avatar_url": "https://avatars.githubusercontent.com/u/12345?v=4"
    },
    "created_at": "2024-01-17T12:30:00Z",
    "html_url": "https://github.com/mycompany/myapp/issues/42#issuecomment-123456789"
  },
  "repository": {
    "name": "myapp",
    "full_name": "mycompany/myapp"
  }
}
Email Reply Processing
How email replies are processed and converted to GitHub comments.

Reply Email Format

To: reply+PROJ-1234@issued.dev
Subject: Re: Support Request #PROJ-1234

This is a reply from the customer that will be posted as a GitHub comment.
POST
/api/webhooks/email
Email reply webhook processing

Request Body

{
  "messageId": "msg_abc123def456",
  "to": "reply+PROJ-1234@issued.dev",
  "from": "customer@example.com",
  "subject": "Re: Support Request #PROJ-1234",
  "text": "Thanks for the quick response! I tried clearing the cache and it worked. The issue is resolved now.",
  "html": "<p>Thanks for the quick response! I tried clearing the cache and it worked. The issue is resolved now.</p>",
  "receivedAt": "2024-01-17T13:15:00Z"
}

File Uploads

POST /api/upload
Upload files for form submissions. Supports images, documents, and text files.
POST
/api/upload
Upload files with form submissions

Request Body

{
  "files": [
    {
      "name": "screenshot.png",
      "type": "image/png",
      "size": 1024576,
      "data": "base64EncodedImageData..."
    },
    {
      "name": "error.log",
      "type": "text/plain",
      "size": 8192,
      "data": "base64EncodedLogData..."
    }
  ],
  "submissionId": "550e8400-e29b-41d4-a716-446655440000"
}

File Restrictions

Size Limits

  • Maximum file size: 10MB per file
  • Maximum total size: 50MB per submission

Supported Formats

  • Images: JPEG, PNG, GIF, SVG
  • Documents: PDF, DOC, DOCX
  • Text: TXT, LOG, CSV

Notifications

GET/POST /api/notifications
Manage notification preferences and test notification delivery.
GET
/api/notifications?projectId=550e8400-e29b-41d4-a716-446655440000
Get notification preferences for a project

Health Monitoring

GET /api/health
Check system health and service status for monitoring and debugging.
GET
/api/health?service=all&detailed=true
Check all services with detailed information

Error Handling

Standard Error Response Format
All API endpoints return errors in a consistent format with appropriate HTTP status codes.

Error Response Structure

{
  "success": false,
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Request validation failed",
    "details": {
      "field": "subject",
      "reason": "Field is required but not provided"
    }
  },
  "timestamp": "2024-01-15T10:30:00Z",
  "requestId": "req_abc123"
}

Common Error Codes

HTTP StatusError CodeDescription
400VALIDATION_FAILEDRequest data is invalid or missing required fields
401UNAUTHORIZEDAuthentication required or invalid credentials
403INVALID_ORIGINRequest origin not whitelisted for this project
404PROJECT_NOT_FOUNDSpecified project does not exist
429RATE_LIMIT_EXCEEDEDToo many requests from this IP address
500INTERNAL_ERRORUnexpected server error

Rate Limiting

API Rate Limits
All API endpoints are subject to rate limiting to ensure fair usage and system stability.

Rate Limit Tiers

Free Tier
  • 10 submissions/hour per IP
  • 100 API calls/hour per user
  • 1 project maximum
Basic Plan
  • 100 submissions/hour per IP
  • 1,000 API calls/hour per user
  • 1 project
Pro Plan
  • 1,000 submissions/hour per IP
  • 10,000 API calls/hour per user
  • Unlimited projects

Rate Limit Headers

All API responses include rate limit information in the headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1705316400
X-RateLimit-Window: 3600
Back to Documentation