Reference

API Reference

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

01Authentication

Authentication

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

request 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
    }
  }
}
response body
{
  "success": true,
  "ticketId": "PROJ-1238",
  "message": "Support request submitted successfully. You will receive an email confirmation shortly.",
  "submissionId": "550e8400-e29b-41d4-a716-446655440004"
}
cURL
curl -X POST "https://api.issued.dev/api/submissions" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer issued_abc123def456" \
  -d "{\n  \"projectId\": \"issued_abc123def456\",\n  \"fields\": {\n    \"subject\": {\n      \"visible\": true,\n      \"required\": true\n    },\n    \"description\": {\n      \"visible\": true,\n      \"required\": true\n    }\n  }\n}"

User Session (Dashboard APIs)

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

GET/api/projects

List projects (requires user session)

response body
{
  "success": true,
  "projects": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "My App Support",
      "githubRepo": "myapp",
      "githubOwner": "mycompany",
      "whitelistedDomains": [
        "myapp.com",
        "*.staging.myapp.com"
      ],
      "whitelistedBundleIds": [
        "com.mycompany.myapp"
      ],
      "createdAt": "2024-01-15T10:30:00Z",
      "updatedAt": "2024-01-16T14:20:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 1,
    "totalPages": 1,
    "hasNext": false,
    "hasPrev": false
  }
}
cURL
curl -X GET "https://api.issued.dev/api/projects" \
  -H "Content-Type: application/json"

Webhook Signature Verification

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

verify-signature.js
// 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');
02Form Submissions

Form Submissions

Submit a support form with embed-level field configuration. POST /api/submissions 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
    }
  }
}
response body
{
  "success": true,
  "ticketId": "PROJ-1234",
  "message": "Support request submitted successfully. You will receive an email confirmation shortly.",
  "submissionId": "550e8400-e29b-41d4-a716-446655440000"
}
cURL
curl -X POST "https://api.issued.dev/api/submissions" \
  -H "Content-Type: application/json" \
  -d "{\n  \"projectId\": \"issued_abc123def456\",\n  \"fields\": {\n    \"subject\": {\n      \"visible\": true,\n      \"required\": true\n    },\n    \"description\": {\n      \"visible\": true,\n      \"required\": true\n    },\n    \"email\": {\n      \"visible\": true,\n      \"required\": false\n    }\n  }\n}"
POST/api/submissions

Form with authenticated user data (hidden fields)

request body
{
  "projectId": "issued_abc123def456",
  "fields": {
    "subject": {
      "visible": true,
      "required": true
    },
    "description": {
      "visible": true,
      "required": true
    },
    "email": {
      "visible": false,
      "value": "user@example.com"
    },
    "name": {
      "visible": false,
      "value": "John Doe"
    },
    "userId": {
      "visible": false,
      "value": "user_123456"
    },
    "planType": {
      "visible": false,
      "value": "premium"
    }
  },
  "metadata": {
    "sdkVersion": "1.0.0",
    "sdkPlatform": "web",
    "pageUrl": "https://myapp.com/support"
  }
}
response body
{
  "success": true,
  "ticketId": "PROJ-1235",
  "message": "Support request submitted successfully. You will receive an email confirmation shortly.",
  "submissionId": "550e8400-e29b-41d4-a716-446655440001"
}
cURL
curl -X POST "https://api.issued.dev/api/submissions" \
  -H "Content-Type: application/json" \
  -d "{\n  \"projectId\": \"issued_abc123def456\",\n  \"fields\": {\n    \"subject\": {\n      \"visible\": true,\n      \"required\": true\n    },\n    \"description\": {\n      \"visible\": true,\n      \"required\": true\n    },\n    \"email\": {\n      \"visible\": false,\n      \"value\": \"user@example.com\"\n    },\n    \"name\": {\n      \"visible\": false,\n      \"value\": \"John Doe\"\n    },\n    \"userId\": {\n      \"visible\": false,\n      \"value\": \"user_123456\"\n    },\n    \"planType\": {\n      \"visible\": false,\n      \"value\": \"premium\"\n    }\n  },\n  \"metadata\": {\n    \"sdkVersion\": \"1.0.0\",\n    \"sdkPlatform\": \"web\",\n    \"pageUrl\": \"https://myapp.com/support\"\n  }\n}"
POST/api/submissions

Form with GitHub-specific fields (labels, assignees, milestone)

request body
{
  "projectId": "issued_abc123def456",
  "fields": {
    "subject": {
      "visible": true,
      "required": true
    },
    "description": {
      "visible": true,
      "required": true
    },
    "email": {
      "visible": true,
      "required": false
    },
    "labels": {
      "visible": false,
      "value": "bug,high-priority,customer-reported"
    },
    "assignees": {
      "visible": false,
      "value": "developer1,support-team"
    },
    "milestone": {
      "visible": false,
      "value": 5
    }
  }
}
response body
{
  "success": true,
  "ticketId": "PROJ-1236",
  "message": "Support request submitted successfully. You will receive an email confirmation shortly.",
  "submissionId": "550e8400-e29b-41d4-a716-446655440002"
}
cURL
curl -X POST "https://api.issued.dev/api/submissions" \
  -H "Content-Type: application/json" \
  -d "{\n  \"projectId\": \"issued_abc123def456\",\n  \"fields\": {\n    \"subject\": {\n      \"visible\": true,\n      \"required\": true\n    },\n    \"description\": {\n      \"visible\": true,\n      \"required\": true\n    },\n    \"email\": {\n      \"visible\": true,\n      \"required\": false\n    },\n    \"labels\": {\n      \"visible\": false,\n      \"value\": \"bug,high-priority,customer-reported\"\n    },\n    \"assignees\": {\n      \"visible\": false,\n      \"value\": \"developer1,support-team\"\n    },\n    \"milestone\": {\n      \"visible\": false,\n      \"value\": 5\n    }\n  }\n}"
POST/api/submissions

Mobile submission with bundle ID validation

request body
{
  "projectId": "issued_abc123def456",
  "fields": {
    "subject": {
      "visible": true,
      "required": true
    },
    "description": {
      "visible": true,
      "required": true
    },
    "email": {
      "visible": false,
      "value": "mobileuser@example.com"
    },
    "userId": {
      "visible": false,
      "value": "mobile_user_789"
    },
    "deviceInfo": {
      "visible": false,
      "value": {
        "platform": "iOS",
        "version": "17.2",
        "model": "iPhone 15 Pro"
      }
    }
  },
  "metadata": {
    "sdkVersion": "1.2.0",
    "sdkPlatform": "ios",
    "bundleId": "com.mycompany.myapp"
  }
}
response body
{
  "success": true,
  "ticketId": "PROJ-1237",
  "message": "Support request submitted successfully. You will receive an email confirmation shortly.",
  "submissionId": "550e8400-e29b-41d4-a716-446655440003"
}
cURL
curl -X POST "https://api.issued.dev/api/submissions" \
  -H "Content-Type: application/json" \
  -d "{\n  \"projectId\": \"issued_abc123def456\",\n  \"fields\": {\n    \"subject\": {\n      \"visible\": true,\n      \"required\": true\n    },\n    \"description\": {\n      \"visible\": true,\n      \"required\": true\n    },\n    \"email\": {\n      \"visible\": false,\n      \"value\": \"mobileuser@example.com\"\n    },\n    \"userId\": {\n      \"visible\": false,\n      \"value\": \"mobile_user_789\"\n    },\n    \"deviceInfo\": {\n      \"visible\": false,\n      \"value\": {\n        \"platform\": \"iOS\",\n        \"version\": \"17.2\",\n        \"model\": \"iPhone 15 Pro\"\n      }\n    }\n  },\n  \"metadata\": {\n    \"sdkVersion\": \"1.2.0\",\n    \"sdkPlatform\": \"ios\",\n    \"bundleId\": \"com.mycompany.myapp\"\n  }\n}"

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
03Project Management

Project Management

GET/api/projects?page=1&limit=10&search=my-app

List all projects for the authenticated user with optional filtering and pagination.

response body
{
  "success": true,
  "projects": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "My App Support",
      "githubRepo": "myapp",
      "githubOwner": "mycompany",
      "whitelistedDomains": [
        "myapp.com",
        "*.staging.myapp.com"
      ],
      "whitelistedBundleIds": [
        "com.mycompany.myapp"
      ],
      "createdAt": "2024-01-15T10:30:00Z",
      "updatedAt": "2024-01-16T14:20:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 1,
    "totalPages": 1,
    "hasNext": false,
    "hasPrev": false
  }
}
cURL
curl -X GET "https://api.issued.dev/api/projects?page=1&limit=10&search=my-app" \
  -H "Content-Type: application/json"
POST/api/projects

Create a new project and link it to a GitHub repository or Linear team, 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"
  ]
}
response body
{
  "success": true,
  "project": {
    "id": "550e8400-e29b-41d4-a716-446655440005",
    "name": "E-commerce Support",
    "githubRepo": "ecommerce-app",
    "githubOwner": "mycompany",
    "whitelistedDomains": [
      "mycompany.com",
      "*.staging.mycompany.com",
      "localhost:3000"
    ],
    "whitelistedBundleIds": [
      "com.mycompany.ecommerce",
      "com.mycompany.ecommerce.staging"
    ],
    "notificationPreferences": {
      "email": true,
      "emailAddress": "support@mycompany.com",
      "webhook": true,
      "webhookUrl": "https://mycompany.com/webhooks/issued",
      "slack": false
    },
    "defaultLabels": [
      "customer-support",
      "auto-created"
    ],
    "defaultAssignees": [
      "support-team"
    ],
    "createdAt": "2024-01-17T09:15:00Z",
    "updatedAt": "2024-01-17T09:15:00Z"
  },
  "message": "Project created successfully"
}
cURL
curl -X POST "https://api.issued.dev/api/projects" \
  -H "Content-Type: application/json" \
  -d "{\n  \"name\": \"E-commerce Support\",\n  \"githubRepo\": \"ecommerce-app\",\n  \"githubOwner\": \"mycompany\",\n  \"notificationPreferences\": {\n    \"email\": true,\n    \"emailAddress\": \"support@mycompany.com\",\n    \"webhook\": true,\n    \"webhookUrl\": \"https://mycompany.com/webhooks/issued\",\n    \"slack\": false\n  },\n  \"whitelistedDomains\": [\n    \"mycompany.com\",\n    \"*.staging.mycompany.com\",\n    \"localhost:3000\"\n  ],\n  \"whitelistedBundleIds\": [\n    \"com.mycompany.ecommerce\",\n    \"com.mycompany.ecommerce.staging\"\n  ],\n  \"defaultLabels\": [\n    \"customer-support\",\n    \"auto-created\"\n  ],\n  \"defaultAssignees\": [\n    \"support-team\"\n  ]\n}"
GET/api/projects/550e8400-e29b-41d4-a716-446655440000

Get detailed information about a specific project (GET /api/projects/{id}).

response body
{
  "success": true,
  "project": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "My App Support",
    "githubRepo": "myapp",
    "githubOwner": "mycompany",
    "githubInstallationId": 12345678,
    "apiKey": "issued_abc123def456",
    "whitelistedDomains": [
      "myapp.com",
      "*.staging.myapp.com"
    ],
    "whitelistedBundleIds": [
      "com.mycompany.myapp"
    ],
    "notificationPreferences": {
      "email": true,
      "emailAddress": "developer@mycompany.com",
      "webhook": false,
      "slack": false
    },
    "defaultLabels": [
      "customer-reported"
    ],
    "defaultAssignees": [
      "support-team"
    ],
    "createdAt": "2024-01-15T10:30:00Z",
    "updatedAt": "2024-01-16T14:20:00Z",
    "stats": {
      "totalSubmissions": 42,
      "pendingSubmissions": 3,
      "avgResponseTime": "4.2 hours"
    }
  }
}
cURL
curl -X GET "https://api.issued.dev/api/projects/550e8400-e29b-41d4-a716-446655440000" \
  -H "Content-Type: application/json"
PUT/api/projects/550e8400-e29b-41d4-a716-446655440000

Update project configuration including security settings and notification preferences (PUT /api/projects/{id}).

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"
  ]
}
response body
{
  "success": true,
  "project": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Updated App Support",
    "githubRepo": "myapp",
    "githubOwner": "mycompany",
    "apiKey": "issued_abc123def456",
    "whitelistedDomains": [
      "myapp.com",
      "*.staging.myapp.com",
      "*.preview.myapp.com"
    ],
    "whitelistedBundleIds": [
      "com.mycompany.myapp",
      "com.mycompany.myapp.beta"
    ],
    "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"
    },
    "defaultLabels": [
      "customer-reported",
      "needs-triage"
    ],
    "defaultAssignees": [
      "support-team",
      "engineering-lead"
    ],
    "updatedAt": "2024-01-17T11:45:00Z"
  },
  "message": "Project updated successfully"
}
cURL
curl -X PUT "https://api.issued.dev/api/projects/550e8400-e29b-41d4-a716-446655440000" \
  -H "Content-Type: application/json" \
  -d "{\n  \"name\": \"Updated App Support\",\n  \"notificationPreferences\": {\n    \"email\": true,\n    \"emailAddress\": \"newsupport@mycompany.com\",\n    \"webhook\": true,\n    \"webhookUrl\": \"https://api.mycompany.com/webhooks/issued\",\n    \"slack\": true,\n    \"slackWebhookUrl\": \"https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX\"\n  },\n  \"whitelistedDomains\": [\n    \"myapp.com\",\n    \"*.staging.myapp.com\",\n    \"*.preview.myapp.com\"\n  ],\n  \"whitelistedBundleIds\": [\n    \"com.mycompany.myapp\",\n    \"com.mycompany.myapp.beta\"\n  ],\n  \"defaultLabels\": [\n    \"customer-reported\",\n    \"needs-triage\"\n  ],\n  \"defaultAssignees\": [\n    \"support-team\",\n    \"engineering-lead\"\n  ]\n}"
04Webhooks

Webhooks

POST/api/webhooks/github

Handles GitHub webhook events, particularly issue comment notifications.

request 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"
  }
}
response body
{
  "success": true,
  "message": "Comment notification sent successfully"
}
cURL
curl -X POST "https://api.issued.dev/api/webhooks/github" \
  -H "Content-Type: application/json" \
  -H "X-GitHub-Event: issue_comment" \
  -H "X-Hub-Signature-256: sha256=..." \
  -d "{\n  \"action\": \"created\",\n  \"issue\": {\n    \"id\": 1,\n    \"number\": 42,\n    \"title\": \"Support Request: Cannot login to account\",\n    \"body\": \"**Email**: customer@example.com\n**Name**: Jane Smith\n**Description**: I'm unable to login to my account...\",\n    \"state\": \"open\",\n    \"html_url\": \"https://github.com/mycompany/myapp/issues/42\"\n  },\n  \"comment\": {\n    \"id\": 123456789,\n    \"body\": \"Hi Jane, thanks for reaching out. Can you please try clearing your browser cache and cookies?\",\n    \"user\": {\n      \"login\": \"support-team\",\n      \"avatar_url\": \"https://avatars.githubusercontent.com/u/12345?v=4\"\n    },\n    \"created_at\": \"2024-01-17T12:30:00Z\",\n    \"html_url\": \"https://github.com/mycompany/myapp/issues/42#issuecomment-123456789\"\n  },\n  \"repository\": {\n    \"name\": \"myapp\",\n    \"full_name\": \"mycompany/myapp\"\n  }\n}"

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"
}
response body
{
  "success": true,
  "message": "Email reply processed and posted to GitHub",
  "githubCommentId": 123456790,
  "githubCommentUrl": "https://github.com/mycompany/myapp/issues/42#issuecomment-123456790"
}
cURL
curl -X POST "https://api.issued.dev/api/webhooks/email" \
  -H "Content-Type: application/json" \
  -d "{\n  \"messageId\": \"msg_abc123def456\",\n  \"to\": \"reply+PROJ-1234@issued.dev\",\n  \"from\": \"customer@example.com\",\n  \"subject\": \"Re: Support Request #PROJ-1234\",\n  \"text\": \"Thanks for the quick response! I tried clearing the cache and it worked. The issue is resolved now.\",\n  \"html\": \"<p>Thanks for the quick response! I tried clearing the cache and it worked. The issue is resolved now.</p>\",\n  \"receivedAt\": \"2024-01-17T13:15:00Z\"\n}"
05File Uploads

File Uploads

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"
}
response body
{
  "success": true,
  "files": [
    {
      "id": "file_abc123def456",
      "name": "screenshot.png",
      "type": "image/png",
      "size": 1024576,
      "url": "https://storage.issued.dev/uploads/550e8400-e29b-41d4-a716-446655440000/screenshot.png",
      "githubUrl": "https://github.com/mycompany/myapp/assets/..."
    },
    {
      "id": "file_def456ghi789",
      "name": "error.log",
      "type": "text/plain",
      "size": 8192,
      "url": "https://storage.issued.dev/uploads/550e8400-e29b-41d4-a716-446655440000/error.log",
      "githubUrl": "https://github.com/mycompany/myapp/files/..."
    }
  ],
  "message": "Files uploaded successfully"
}
cURL
curl -X POST "https://api.issued.dev/api/upload" \
  -H "Content-Type: application/json" \
  -d "{\n  \"files\": [\n    {\n      \"name\": \"screenshot.png\",\n      \"type\": \"image/png\",\n      \"size\": 1024576,\n      \"data\": \"base64EncodedImageData...\"\n    },\n    {\n      \"name\": \"error.log\",\n      \"type\": \"text/plain\",\n      \"size\": 8192,\n      \"data\": \"base64EncodedLogData...\"\n    }\n  ],\n  \"submissionId\": \"550e8400-e29b-41d4-a716-446655440000\"\n}"

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
06Notifications

Notifications

Manage notification preferences and test notification delivery via GET/POST /api/notifications.

GET/api/notifications?projectId=550e8400-e29b-41d4-a716-446655440000

Get notification preferences for a project

response body
{
  "success": true,
  "preferences": {
    "email": true,
    "emailAddress": "developer@example.com",
    "webhook": false,
    "webhookUrl": null,
    "slack": false,
    "slackWebhookUrl": null
  }
}
cURL
curl -X GET "https://api.issued.dev/api/notifications?projectId=550e8400-e29b-41d4-a716-446655440000" \
  -H "Content-Type: application/json"
POST/api/notifications

Update notification preferences

request body
{
  "projectId": "550e8400-e29b-41d4-a716-446655440000",
  "preferences": {
    "email": true,
    "emailAddress": "notifications@mycompany.com",
    "webhook": true,
    "webhookUrl": "https://myapp.com/webhooks/issued",
    "slack": true,
    "slackWebhookUrl": "https://hooks.slack.com/services/..."
  }
}
response body
{
  "success": true,
  "message": "Notification preferences updated successfully"
}
cURL
curl -X POST "https://api.issued.dev/api/notifications" \
  -H "Content-Type: application/json" \
  -d "{\n  \"projectId\": \"550e8400-e29b-41d4-a716-446655440000\",\n  \"preferences\": {\n    \"email\": true,\n    \"emailAddress\": \"notifications@mycompany.com\",\n    \"webhook\": true,\n    \"webhookUrl\": \"https://myapp.com/webhooks/issued\",\n    \"slack\": true,\n    \"slackWebhookUrl\": \"https://hooks.slack.com/services/...\"\n  }\n}"
POST/api/notifications/test

Send test notifications

request body
{
  "projectId": "550e8400-e29b-41d4-a716-446655440000",
  "type": "email"
}
response body
{
  "success": true,
  "message": "Test notification sent successfully"
}
cURL
curl -X POST "https://api.issued.dev/api/notifications/test" \
  -H "Content-Type: application/json" \
  -d "{\n  \"projectId\": \"550e8400-e29b-41d4-a716-446655440000\",\n  \"type\": \"email\"\n}"

The type field accepts "email", "webhook", or "slack".

07Health Monitoring

Health Monitoring

Check system health and service status for monitoring and debugging via GET /api/health.

GET/api/health?service=all&detailed=true

Check all services with detailed information

response body
{
  "status": "healthy",
  "timestamp": "2024-01-17T14:30:00Z",
  "uptime": 86400,
  "version": "1.0.0",
  "services": {
    "database": {
      "status": "healthy",
      "responseTime": 45,
      "lastChecked": "2024-01-17T14:30:00Z"
    },
    "github": {
      "status": "healthy",
      "responseTime": 123,
      "lastChecked": "2024-01-17T14:30:00Z"
    },
    "email": {
      "status": "healthy",
      "responseTime": 12,
      "lastChecked": "2024-01-17T14:30:00Z"
    }
  }
}
cURL
curl -X GET "https://api.issued.dev/api/health?service=all&detailed=true" \
  -H "Content-Type: application/json"
GET/api/health?service=database

Check database connectivity

response body
{
  "status": "healthy",
  "timestamp": "2024-01-17T14:30:00Z",
  "uptime": 86400,
  "version": "1.0.0",
  "services": {
    "database": {
      "status": "healthy",
      "responseTime": 45,
      "lastChecked": "2024-01-17T14:30:00Z"
    }
  }
}
cURL
curl -X GET "https://api.issued.dev/api/health?service=database" \
  -H "Content-Type: application/json"
GET/api/health?service=github

Check GitHub API status

response body
{
  "status": "healthy",
  "timestamp": "2024-01-17T14:30:00Z",
  "uptime": 86400,
  "version": "1.0.0",
  "services": {
    "github": {
      "status": "healthy",
      "responseTime": 123,
      "lastChecked": "2024-01-17T14:30:00Z"
    }
  }
}
cURL
curl -X GET "https://api.issued.dev/api/health?service=github" \
  -H "Content-Type: application/json"
GET/api/health?service=email

Check email service configuration

response body
{
  "status": "healthy",
  "timestamp": "2024-01-17T14:30:00Z",
  "uptime": 86400,
  "version": "1.0.0",
  "services": {
    "email": {
      "status": "healthy",
      "responseTime": 12,
      "lastChecked": "2024-01-17T14:30:00Z"
    }
  }
}
cURL
curl -X GET "https://api.issued.dev/api/health?service=email" \
  -H "Content-Type: application/json"
08Error Handling

Error Handling

All API endpoints return errors in a consistent format with appropriate HTTP status codes.

Error Response Structure

error response
{
  "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
09Rate Limiting

Rate Limiting

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

Operational Rate Limits

Unauthenticated
  • 10 submissions/hour per IP
  • 100 API calls/hour per user
  • Abuse protection before account context
Authenticated
  • 100 submissions/hour per IP
  • 1,000 API calls/hour per user
  • Normal protected dashboard usage
Elevated
  • 1,000 submissions/hour per IP
  • 10,000 API calls/hour per user
  • High-throughput operational allowance

Rate Limit Headers

All API responses include rate limit information in the headers:

response headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1705316400
X-RateLimit-Window: 3600