REST API Reference - ericfitz/tmi GitHub Wiki
REST API Reference
This page documents every REST API endpoint in TMI, organized by resource category. For high-level design principles and authentication details, see API-Overview. For common usage patterns and workflows, see API-Workflows.
API Specification
OpenAPI Documentation
The complete API specification is available in OpenAPI 3.0.3 format:
| Specification file | tmi-openapi.json |
| Version | 1.4.0-rc.0 |
| Format | JSON with $ref references |
| Interactive viewer | Swagger Editor (import the file above) |
Base URL
Development: http://localhost:8080
All endpoints use the root path directly (no /api/v1 prefix).
Common Patterns
Before diving into individual endpoints, review these patterns that apply across the entire API.
Error Responses
All errors follow a consistent format:
{
"error": "not_found",
"error_description": "Threat model not found",
"details": {
"code": "resource_not_found",
"suggestion": "Check the threat model ID and try again",
"context": {
"resource_type": "threat_model"
}
},
"error_uri": "https://docs.tmi.dev/errors/not_found"
}
| Field | Type | Required | Description |
|---|---|---|---|
error |
string | Yes | Machine-readable error code |
error_description |
string | Yes | Human-readable error description |
details |
object | No | Additional context with code, suggestion, and context sub-fields |
error_uri |
string | No | Link to error documentation |
Pagination
All list endpoints return paginated responses:
{
"<resource_name>": [...],
"total": 100,
"limit": 20,
"offset": 0
}
The array key matches the resource name (for example, threat_models, diagrams, threats, addons).
PATCH Operations (JSON Patch)
All PATCH endpoints use RFC 6902 JSON Patch format:
[
{ "op": "replace", "path": "/name", "value": "New Name" },
{ "op": "add", "path": "/description", "value": "Added description" },
{ "op": "remove", "path": "/issue_uri" }
]
Supported operations: add, remove, replace, test.
Authorization Model
TMI uses a principal-based authorization model on threat models. Each authorization entry has the following structure:
{
"principal_type": "group",
"provider": "google",
"provider_id": "security-team",
"role": "writer",
"display_name": "Security Team",
"email": null
}
| Field | Type | Description |
|---|---|---|
principal_type |
string | user or group |
provider |
string | Identity provider (for example, google, github, microsoft, * for TMI-managed) |
provider_id |
string | Provider-assigned identifier (email for users, group name for groups) |
role |
string | reader, writer, or owner |
display_name |
string (optional) | Human-readable display name |
email |
email (optional) | Email address (required for users) |
Roles:
- owner -- Full permissions including delete and permission management
- writer -- Read and write access; cannot delete or change permissions
- reader -- Read-only access
Special Groups:
everyone-- All authenticated users
Rate Limiting
TMI implements a four-tier rate limiting strategy:
- Public Discovery -- IP-based rate limiting
- Auth Flows -- Multi-scope limits (session, IP, user identifier)
- Resource Operations -- Per-user rate limiting (configurable via admin quotas)
- Webhooks -- Multiple limits including subscriptions and events (configurable via admin quotas)
When rate limited, the API returns 429 Too Many Requests with X-RateLimit-* and Retry-After headers.
For complete rate limiting documentation including client integration examples, see API-Rate-Limiting.
Endpoint Categories
Core Resources
- Threat Models -- Threat modeling workspaces
- Diagrams -- Data flow diagrams (sub-resource of threat models)
- Threats -- Security threats (sub-resource of threat models)
- Assets -- System assets (sub-resource of threat models)
- Documents -- Reference documents (sub-resource of threat models)
- Notes -- Markdown notes (sub-resource of threat models)
- Repositories -- Source code repositories (sub-resource of threat models)
- Metadata -- Custom metadata (sub-resource of multiple entity types)
- Audit Trail -- Change history and rollback
Organizational Resources
Intake and Triage
Integration Resources
- Webhooks -- Webhook subscriptions and deliveries (admin)
- Addons -- Addon registrations and invocations
- Webhook Delivery Status -- Delivery tracking
User and Admin Resources
- Current User -- Self-service user profile and preferences (
/me) - Admin Users -- Administrative user management
- Admin Groups -- Administrative group management
- Admin Quotas -- Rate limit quota management
- Admin Settings -- System settings management
- SAML Users -- SAML user listing
System Resources
- API Info -- Service information and health status
- Authentication -- OAuth2 endpoints
- SAML -- SAML authentication endpoints
- Client Configuration -- Client configuration endpoint
- Well-Known Endpoints -- Discovery metadata
- WebSocket Ticket -- WebSocket authentication
Threat Models
Threat models are the primary workspace for security analysis.
List Threat Models
GET /threat_models
Authorization: Bearer {token}
Query Parameters:
limit(integer): Number of results (default: 20)offset(integer): Pagination offset (default: 0)owner(string): Filter by owner name or emailname(string): Filter by name (case-insensitive substring match)description(string): Filter by description (partial match)issue_uri(string): Filter by issue URI (partial match)created_after(ISO 8601): Filter by creation datecreated_before(ISO 8601): Filter by creation datemodified_after(ISO 8601): Filter by modification datemodified_before(ISO 8601): Filter by modification datestatus(string): Filter by status (OR logic, repeatable)status_updated_after(RFC3339): Filter by status update timestampstatus_updated_before(RFC3339): Filter by status update timestampinclude_deleted(boolean): Include soft-deleted entities (requires owner or admin)security_reviewer(string): Filter by security reviewer (partial match on email or name; useis:null/is:notnullfor presence)
Response (200 OK):
{
"threat_models": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Production API Security",
"description": "Threat model for production API",
"owner": {
"principal_type": "user",
"provider": "google",
"provider_id": "[email protected]",
"display_name": "Alice Smith",
"email": "[email protected]"
},
"created_by": {
"principal_type": "user",
"provider": "google",
"provider_id": "[email protected]",
"display_name": "Alice Smith",
"email": "[email protected]"
},
"created_at": "2025-01-15T10:00:00Z",
"modified_at": "2025-01-15T15:30:00Z",
"status": "In progress",
"status_updated": "2025-01-15T12:00:00Z",
"threat_model_framework": "STRIDE",
"security_reviewer": null,
"issue_uri": null,
"deleted_at": null,
"diagram_count": 3,
"document_count": 2,
"note_count": 1,
"asset_count": 5,
"threat_count": 12,
"repo_count": 2
}
],
"total": 25,
"limit": 20,
"offset": 0
}
Get Threat Model
GET /threat_models/{threat_model_id}
Authorization: Bearer {token}
Response (200 OK):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Production API Security",
"description": "Comprehensive threat model for production API services",
"owner": {
"principal_type": "user",
"provider": "google",
"provider_id": "[email protected]",
"display_name": "Alice Smith",
"email": "[email protected]"
},
"created_by": {
"principal_type": "user",
"provider": "google",
"provider_id": "[email protected]",
"display_name": "Alice Smith",
"email": "[email protected]"
},
"created_at": "2025-01-15T10:00:00Z",
"modified_at": "2025-01-15T15:30:00Z",
"threat_model_framework": "STRIDE",
"status": "In progress",
"status_updated": "2025-01-15T12:00:00Z",
"is_confidential": false,
"issue_uri": null,
"project_id": null,
"security_reviewer": null,
"alias": [],
"authorization": [
{
"principal_type": "group",
"provider": "google",
"provider_id": "security-team",
"role": "writer",
"display_name": "Security Team",
"email": null
}
],
"metadata": [],
"diagrams": [...],
"threats": [...],
"assets": [...],
"documents": [...],
"notes": [...],
"repositories": [...]
}
Create Threat Model
POST /threat_models
Authorization: Bearer {token}
Content-Type: application/json
{
"name": "My Threat Model",
"description": "Security analysis for new feature",
"threat_model_framework": "STRIDE",
"authorization": [
{
"principal_type": "group",
"provider": "google",
"provider_id": "security-team",
"role": "writer"
}
]
}
Response (201 Created): Returns the full created threat model object.
Important: Do not include server-generated fields in create requests:
id-- Generated by the server as a UUIDowner-- Extracted from the JWT tokencreated_at,modified_at-- Set by the server- Calculated counts (
diagram_count, etc.) -- Computed automatically
Update Threat Model
Full Update (PUT):
PUT /threat_models/{threat_model_id}
Authorization: Bearer {token}
Content-Type: application/json
{
"name": "Updated Name",
"description": "Updated description",
"threat_model_framework": "STRIDE",
"authorization": [...]
}
Partial Update (PATCH - RFC 6902 JSON Patch):
PATCH /threat_models/{threat_model_id}
Authorization: Bearer {token}
Content-Type: application/json
[
{ "op": "replace", "path": "/name", "value": "New Name Only" }
]
Response (200 OK): Returns updated resource.
Delete Threat Model
DELETE /threat_models/{threat_model_id}
Authorization: Bearer {token}
Response (204 No Content)
Note: Requires the owner role. Deletion cascades to all related sub-resources. Supports soft-delete (tombstone).
Restore Threat Model
POST /threat_models/{threat_model_id}/restore
Authorization: Bearer {token}
Response (200 OK): Restores a soft-deleted threat model.
Diagrams
Data flow diagrams are sub-resources of threat models. There are no standalone /diagrams endpoints.
List Diagrams
GET /threat_models/{threat_model_id}/diagrams
Authorization: Bearer {token}
Query Parameters: limit, offset, include_deleted
Response (200 OK):
{
"diagrams": [
{
"id": "diagram-uuid",
"name": "System Architecture",
"description": "Main system data flow",
"type": "DFD-1.0.0",
"created_at": "2025-01-15T10:00:00Z",
"modified_at": "2025-01-15T14:30:00Z",
"deleted_at": null,
"include_in_report": true,
"image": {
"svg": "base64-encoded-svg-data",
"update_vector": 3
}
}
],
"total": 3,
"limit": 20,
"offset": 0
}
Note: The list response returns DiagramListItem objects that exclude the full cells array for performance. Use the individual GET endpoint to retrieve the complete diagram data including cells.
Get Diagram
GET /threat_models/{threat_model_id}/diagrams/{diagram_id}
Authorization: Bearer {token}
Response (200 OK): Returns a DfdDiagram object with the full cells array:
{
"id": "diagram-uuid",
"name": "System Architecture",
"description": "Main system data flow",
"cells": [...],
"color_palette": [...],
"metadata": [],
"image": {
"svg": "base64-encoded-svg",
"update_vector": 3
},
"include_in_report": true,
"created_at": "2025-01-15T10:00:00Z",
"modified_at": "2025-01-15T14:30:00Z",
"deleted_at": null
}
Create Diagram
POST /threat_models/{threat_model_id}/diagrams
Authorization: Bearer {token}
Content-Type: application/json
{
"name": "System Architecture",
"cells": [],
"description": "Main system data flow"
}
Update Diagram
- PUT
/threat_models/{threat_model_id}/diagrams/{diagram_id}- Full update - PATCH
/threat_models/{threat_model_id}/diagrams/{diagram_id}- JSON Patch (RFC 6902)
Delete Diagram
DELETE /threat_models/{threat_model_id}/diagrams/{diagram_id}
Authorization: Bearer {token}
Response (204 No Content)
Restore Diagram
POST /threat_models/{threat_model_id}/diagrams/{diagram_id}/restore
Authorization: Bearer {token}
Diagram Model
GET /threat_models/{threat_model_id}/diagrams/{diagram_id}/model
Authorization: Bearer {token}
Returns a derived model representation of the diagram.
Diagram Collaboration Sessions
- POST
/threat_models/{threat_model_id}/diagrams/{diagram_id}/collaborate- Create session - GET
/threat_models/{threat_model_id}/diagrams/{diagram_id}/collaborate- Get session - DELETE
/threat_models/{threat_model_id}/diagrams/{diagram_id}/collaborate- End session
For real-time collaborative editing, use the WebSocket API. See WebSocket-API-Reference.
Threats
Security threats are sub-resources of threat models. There are no standalone /threats endpoints. Threats support bulk operations for batch processing.
List Threats
GET /threat_models/{threat_model_id}/threats
Authorization: Bearer {token}
Query Parameters: limit, offset, include_deleted, plus threat-specific filters
Response (200 OK):
{
"threats": [
{
"id": "threat-uuid",
"threat_model_id": "tm-uuid",
"name": "SQL Injection Vulnerability",
"description": "User input not sanitized",
"threat_type": ["Tampering"],
"severity": "high",
"priority": "P1",
"status": "identified",
"mitigation": "Use parameterized queries",
"mitigated": false,
"score": 8.5,
"issue_uri": null,
"diagram_id": null,
"cell_id": null,
"asset_id": null,
"include_in_report": true,
"cwe_id": ["CWE-89"],
"cvss": [],
"metadata": [],
"created_at": "2025-01-15T11:00:00Z",
"modified_at": "2025-01-15T11:00:00Z",
"deleted_at": null
}
],
"total": 12,
"limit": 20,
"offset": 0
}
Create Threat
POST /threat_models/{threat_model_id}/threats
Authorization: Bearer {token}
Content-Type: application/json
{
"name": "SQL Injection Vulnerability",
"description": "Detailed description",
"threat_type": ["Tampering"],
"severity": "high",
"mitigation": "Use parameterized queries"
}
Bulk Threat Operations
- POST
/threat_models/{threat_model_id}/threats/bulk- Bulk create - PUT
/threat_models/{threat_model_id}/threats/bulk- Bulk update - PATCH
/threat_models/{threat_model_id}/threats/bulk- Bulk patch - DELETE
/threat_models/{threat_model_id}/threats/bulk- Bulk delete
Update/Delete/Restore Threat
- PUT
/threat_models/{threat_model_id}/threats/{threat_id}- Full update - PATCH
/threat_models/{threat_model_id}/threats/{threat_id}- JSON Patch - DELETE
/threat_models/{threat_model_id}/threats/{threat_id}- Delete - POST
/threat_models/{threat_model_id}/threats/{threat_id}/restore- Restore
Assets
Assets are sub-resources of threat models.
Endpoints
- GET
/threat_models/{threat_model_id}/assets- List assets - POST
/threat_models/{threat_model_id}/assets- Create asset - GET
/threat_models/{threat_model_id}/assets/{asset_id}- Get asset - PUT
/threat_models/{threat_model_id}/assets/{asset_id}- Full update - PATCH
/threat_models/{threat_model_id}/assets/{asset_id}- JSON Patch - DELETE
/threat_models/{threat_model_id}/assets/{asset_id}- Delete - POST
/threat_models/{threat_model_id}/assets/{asset_id}/restore- Restore - POST
/threat_models/{threat_model_id}/assets/bulk- Bulk create - PUT
/threat_models/{threat_model_id}/assets/bulk- Bulk upsert
Asset Types: data, hardware, infrastructure, personnel, service, software
Documents
Documents are sub-resources of threat models.
Endpoints
- GET
/threat_models/{threat_model_id}/documents- List documents - POST
/threat_models/{threat_model_id}/documents- Create document - GET
/threat_models/{threat_model_id}/documents/{document_id}- Get document - PUT
/threat_models/{threat_model_id}/documents/{document_id}- Full update - PATCH
/threat_models/{threat_model_id}/documents/{document_id}- JSON Patch - DELETE
/threat_models/{threat_model_id}/documents/{document_id}- Delete - POST
/threat_models/{threat_model_id}/documents/{document_id}/restore- Restore - POST
/threat_models/{threat_model_id}/documents/bulk- Bulk create - PUT
/threat_models/{threat_model_id}/documents/bulk- Bulk upsert
Notes
Notes are sub-resources of threat models.
Endpoints
- GET
/threat_models/{threat_model_id}/notes- List notes - POST
/threat_models/{threat_model_id}/notes- Create note - GET
/threat_models/{threat_model_id}/notes/{note_id}- Get note - PUT
/threat_models/{threat_model_id}/notes/{note_id}- Full update - PATCH
/threat_models/{threat_model_id}/notes/{note_id}- JSON Patch - DELETE
/threat_models/{threat_model_id}/notes/{note_id}- Delete - POST
/threat_models/{threat_model_id}/notes/{note_id}/restore- Restore
Repositories
Source code repositories are sub-resources of threat models.
Endpoints
- GET
/threat_models/{threat_model_id}/repositories- List repositories - POST
/threat_models/{threat_model_id}/repositories- Create repository - GET
/threat_models/{threat_model_id}/repositories/{repository_id}- Get repository - PUT
/threat_models/{threat_model_id}/repositories/{repository_id}- Full update - PATCH
/threat_models/{threat_model_id}/repositories/{repository_id}- JSON Patch - DELETE
/threat_models/{threat_model_id}/repositories/{repository_id}- Delete - POST
/threat_models/{threat_model_id}/repositories/{repository_id}/restore- Restore - POST
/threat_models/{threat_model_id}/repositories/bulk- Bulk create - PUT
/threat_models/{threat_model_id}/repositories/bulk- Bulk upsert
Metadata
Custom key-value metadata can be attached to multiple entity types: threat models, diagrams, documents, notes, repositories, assets, threats, surveys, survey responses, teams, and projects.
Metadata Endpoints (per entity)
For each entity type, metadata endpoints follow this pattern (example for diagrams):
- GET
.../diagrams/{diagram_id}/metadata- Get all metadata - POST
.../diagrams/{diagram_id}/metadata- Create metadata entry - GET
.../diagrams/{diagram_id}/metadata/{key}- Get by key - PUT
.../diagrams/{diagram_id}/metadata/{key}- Update by key - DELETE
.../diagrams/{diagram_id}/metadata/{key}- Delete by key - POST
.../diagrams/{diagram_id}/metadata/bulk- Bulk create - PATCH
.../diagrams/{diagram_id}/metadata/bulk- Bulk upsert - PUT
.../diagrams/{diagram_id}/metadata/bulk- Bulk replace
Audit Trail
Change history for threat models and their sub-resources.
Endpoints
- GET
/threat_models/{threat_model_id}/audit_trail- Threat model audit trail - GET
/threat_models/{threat_model_id}/audit_trail/{entry_id}- Get specific audit entry - POST
/threat_models/{threat_model_id}/audit_trail/{entry_id}/rollback- Rollback to version - GET
/threat_models/{threat_model_id}/diagrams/{diagram_id}/audit_trail- Diagram audit trail - GET
/threat_models/{threat_model_id}/documents/{document_id}/audit_trail- Document audit trail - GET
/threat_models/{threat_model_id}/notes/{note_id}/audit_trail- Note audit trail - GET
/threat_models/{threat_model_id}/repositories/{repository_id}/audit_trail- Repository audit trail - GET
/threat_models/{threat_model_id}/assets/{asset_id}/audit_trail- Asset audit trail - GET
/threat_models/{threat_model_id}/threats/{threat_id}/audit_trail- Threat audit trail
Audit Entry Change Types: created, updated, patched, deleted, restored, rolled_back
Teams
Team management for organizational grouping.
Endpoints
- GET
/teams- List teams - POST
/teams- Create team - GET
/teams/{team_id}- Get team - PUT
/teams/{team_id}- Full update - PATCH
/teams/{team_id}- JSON Patch - DELETE
/teams/{team_id}- Delete team
Team Notes
- GET
/teams/{team_id}/notes- List team notes - POST
/teams/{team_id}/notes- Create team note - GET
/teams/{team_id}/notes/{team_note_id}- Get team note - PUT
/teams/{team_id}/notes/{team_note_id}- Update team note - PATCH
/teams/{team_id}/notes/{team_note_id}- JSON Patch - DELETE
/teams/{team_id}/notes/{team_note_id}- Delete team note
Team Metadata
Standard metadata endpoints at /teams/{team_id}/metadata/...
Projects
Project management for organizing threat models.
Endpoints
- GET
/projects- List projects - POST
/projects- Create project - GET
/projects/{project_id}- Get project - PUT
/projects/{project_id}- Full update - PATCH
/projects/{project_id}- JSON Patch - DELETE
/projects/{project_id}- Delete project
Project Notes
- GET
/projects/{project_id}/notes- List project notes - POST
/projects/{project_id}/notes- Create project note - GET
/projects/{project_id}/notes/{project_note_id}- Get project note - PUT
/projects/{project_id}/notes/{project_note_id}- Update project note - PATCH
/projects/{project_id}/notes/{project_note_id}- JSON Patch - DELETE
/projects/{project_id}/notes/{project_note_id}- Delete project note
Project Metadata
Standard metadata endpoints at /projects/{project_id}/metadata/...
Surveys
Surveys provide structured intake forms for initiating threat model requests.
Admin Survey Management
- GET
/admin/surveys- List surveys (admin) - POST
/admin/surveys- Create survey (admin) - GET
/admin/surveys/{survey_id}- Get survey (admin) - PUT
/admin/surveys/{survey_id}- Update survey (admin) - PATCH
/admin/surveys/{survey_id}- Patch survey (admin) - DELETE
/admin/surveys/{survey_id}- Delete survey (admin)
Intake Surveys (User-facing)
- GET
/intake/surveys- List available surveys - GET
/intake/surveys/{survey_id}- Get survey details
Survey Responses
- GET
/intake/survey_responses- List user's survey responses - POST
/intake/survey_responses- Create survey response - GET
/intake/survey_responses/{survey_response_id}- Get survey response - PUT
/intake/survey_responses/{survey_response_id}- Update survey response - PATCH
/intake/survey_responses/{survey_response_id}- Patch survey response - DELETE
/intake/survey_responses/{survey_response_id}- Delete survey response
Triage
Triage workflow for reviewing survey responses and creating threat models.
Triage Survey Responses
- GET
/triage/survey_responses- List survey responses for triage - GET
/triage/survey_responses/{survey_response_id}- Get survey response - PATCH
/triage/survey_responses/{survey_response_id}- Update triage status - POST
/triage/survey_responses/{survey_response_id}/create_threat_model- Create threat model from response
Triage Notes
- GET
/triage/survey_responses/{survey_response_id}/triage_notes- List triage notes - POST
/triage/survey_responses/{survey_response_id}/triage_notes- Create triage note - GET
/triage/survey_responses/{survey_response_id}/triage_notes/{triage_note_id}- Get triage note
Webhooks
Webhook subscriptions and deliveries are managed under the /admin/webhooks/ path. All webhook management endpoints require administrator privileges.
Create Webhook Subscription
POST /admin/webhooks/subscriptions
Authorization: Bearer {admin-token}
Content-Type: application/json
{
"name": "My Integration",
"url": "https://your-domain.com/webhooks/tmi",
"events": ["threat_model.created", "threat_model.updated"],
"secret": "your-hmac-secret",
"threat_model_id": "tm-uuid"
}
Response (201 Created):
{
"id": "webhook-uuid",
"status": "pending_verification",
"name": "My Integration",
"url": "https://your-domain.com/webhooks/tmi",
"events": ["threat_model.created", "threat_model.updated"],
"owner_id": "user-uuid",
"threat_model_id": "tm-uuid",
"created_at": "2025-01-15T10:00:00Z",
"modified_at": "2025-01-15T10:00:00Z",
"challenges_sent": 0,
"publication_failures": 0,
"last_successful_use": null
}
Challenge-Response: TMI sends a challenge request to verify your endpoint before activating the subscription.
List Webhook Subscriptions
GET /admin/webhooks/subscriptions
Authorization: Bearer {admin-token}
Get Webhook Subscription
GET /admin/webhooks/subscriptions/{webhook_id}
Authorization: Bearer {admin-token}
Delete Webhook Subscription
DELETE /admin/webhooks/subscriptions/{webhook_id}
Authorization: Bearer {admin-token}
Test Webhook Subscription
POST /admin/webhooks/subscriptions/{webhook_id}/test
Authorization: Bearer {admin-token}
List Webhook Deliveries
GET /admin/webhooks/deliveries
Authorization: Bearer {admin-token}
Get Webhook Delivery
GET /admin/webhooks/deliveries/{delivery_id}
Authorization: Bearer {admin-token}
Response (200 OK):
{
"id": "delivery-uuid",
"subscription_id": "webhook-uuid",
"event_type": "threat_model.created",
"status": "delivered",
"status_message": "Delivered successfully",
"status_percent": 100,
"attempts": 1,
"created_at": "2025-01-15T12:00:00Z",
"delivered_at": "2025-01-15T12:00:01Z",
"last_activity_at": "2025-01-15T12:00:01Z",
"next_retry_at": null,
"last_error": null,
"addon_id": null,
"invoked_by": null,
"payload": {}
}
See Webhook-Integration for complete webhook documentation.
Webhook Delivery Status
Webhook consumers use these endpoints to check or update delivery status. GET requests require Bearer token authentication; status updates use HMAC authentication.
Get Delivery Status
GET /webhook-deliveries/{delivery_id}
Authorization: Bearer {token}
Update Delivery Status
POST /webhook-deliveries/{delivery_id}/status
Addon endpoints use this to report processing progress back to TMI via HMAC-authenticated callbacks.
Addons
Addon registrations and invocations.
List Addons
GET /addons
Authorization: Bearer {token}
Query Parameters:
threat_model_id(UUID): Filter by threat modellimit(integer): Pagination limitoffset(integer): Pagination offset
Response (200 OK):
{
"addons": [
{
"id": "addon-uuid",
"name": "STRIDE Analysis",
"description": "Automated STRIDE analysis",
"icon": "material-symbols:security",
"objects": ["threat_model", "asset"],
"parameters": [...],
"webhook_id": "webhook-uuid",
"threat_model_id": null,
"created_at": "2025-01-15T10:00:00Z"
}
],
"total": 5,
"limit": 20,
"offset": 0
}
Get Addon
GET /addons/{id}
Authorization: Bearer {token}
Create Addon
POST /addons
Authorization: Bearer {token}
Content-Type: application/json
{
"name": "STRIDE Analysis",
"webhook_id": "webhook-uuid",
"description": "Automated STRIDE analysis",
"icon": "material-symbols:security",
"objects": ["threat_model", "asset"],
"parameters": [...]
}
Delete Addon
DELETE /addons/{id}
Authorization: Bearer {token}
Invoke Addon
POST /addons/{id}/invoke
Authorization: Bearer {token}
Content-Type: application/json
{
"threat_model_id": "tm-uuid",
"object_type": "asset",
"object_id": "asset-uuid",
"payload": {
"analysis_type": "full"
}
}
Response (202 Accepted):
{
"delivery_id": "delivery-uuid",
"status": "pending",
"created_at": "2025-01-15T12:00:00Z"
}
Track invocation progress via GET /webhook-deliveries/{delivery_id}.
See Addon-System for complete addon documentation.
Current User
Self-service endpoints for the authenticated user.
Get Current User Profile
GET /me
Authorization: Bearer {token}
Response (200 OK):
{
"principal_type": "user",
"provider": "google",
"provider_id": "[email protected]",
"display_name": "Alice Smith",
"email": "[email protected]",
"is_admin": false,
"is_security_reviewer": false,
"groups": [
{
"internal_uuid": "group-uuid",
"group_name": "security-team",
"provider": "*"
}
]
}
Additional /me Endpoints
- DELETE
/me- Delete user account (two-step challenge-response) - POST
/me/logout- Logout current user - GET
/me/preferences- Get user preferences - POST
/me/preferences- Create user preferences - PUT
/me/preferences- Update user preferences - GET
/me/sessions- List active collaboration sessions - POST
/me/transfer- Transfer ownership of all owned resources - GET
/me/groups- List user's groups - GET
/me/groups/{internal_uuid}/members- List members of a group - GET
/me/client_credentials- List client credentials - POST
/me/client_credentials- Create client credential - DELETE
/me/client_credentials/{credential_id}- Delete client credential
Admin Users
These endpoints require administrator privileges.
List All Users
GET /admin/users
Authorization: Bearer {admin-token}
Query Parameters:
provider(string): Filter by identity provideremail(string): Filter by email (case-insensitive substring match)created_after(RFC3339): Filter by creation datecreated_before(RFC3339): Filter by creation datelast_login_after(RFC3339): Filter by last login datelast_login_before(RFC3339): Filter by last login datelimit(integer): Number of results (default: 50, max: 500)offset(integer): Pagination offset (default: 0)sort_by(string): Sort field (created_at,last_login,email)sort_order(string): Sort direction (asc,desc)
Get User
GET /admin/users/{internal_uuid}
Authorization: Bearer {admin-token}
Update User
PATCH /admin/users/{internal_uuid}
Authorization: Bearer {admin-token}
Content-Type: application/json
{
"email": "[email protected]",
"name": "Updated Name",
"email_verified": true
}
Delete User
DELETE /admin/users/{internal_uuid}
Authorization: Bearer {admin-token}
Behavior:
- Transfers ownership of threat models to alternate owners when available
- Deletes threat models that have no alternate owners
- Removes all user permissions and sessions
- Logs the deletion in the audit trail with statistics
Response: 204 No Content
Transfer User Ownership
POST /admin/users/{internal_uuid}/transfer
Authorization: Bearer {admin-token}
Automation (Service) Accounts
POST /admin/users/automation
Authorization: Bearer {admin-token}
Admin User Client Credentials
- GET
/admin/users/{internal_uuid}/client_credentials- List credentials - POST
/admin/users/{internal_uuid}/client_credentials- Create credential - DELETE
/admin/users/{internal_uuid}/client_credentials/{credential_id}- Delete credential
Admin Groups
Groups can originate from an identity provider (SAML or OAuth) or be TMI-managed groups (provider *).
Endpoints
- GET
/admin/groups- List all groups - POST
/admin/groups- Create TMI-managed group (provider="*") - GET
/admin/groups/{internal_uuid}- Get group details - PATCH
/admin/groups/{internal_uuid}- Update group - DELETE
/admin/groups/{internal_uuid}- Delete group (cannot delete protected groups likeeveryone)
Group Membership
- GET
/admin/groups/{internal_uuid}/members- List members - POST
/admin/groups/{internal_uuid}/members- Add member - DELETE
/admin/groups/{internal_uuid}/members/{member_uuid}- Remove member
You can manage members for TMI-managed groups only. Identity provider group membership is managed by the identity provider itself.
Admin Quotas
Per-user quota management for rate limiting.
User API Quotas
- GET
/admin/quotas/users- List all user API quotas - GET
/admin/quotas/users/{user_id}- Get quota - PUT
/admin/quotas/users/{user_id}- Update quota - DELETE
/admin/quotas/users/{user_id}- Delete quota (revert to defaults)
Webhook Quotas
- GET
/admin/quotas/webhooks- List all webhook quotas - GET
/admin/quotas/webhooks/{user_id}- Get quota - PUT
/admin/quotas/webhooks/{user_id}- Update quota - DELETE
/admin/quotas/webhooks/{user_id}- Delete quota
Addon Invocation Quotas
- GET
/admin/quotas/addons- List all addon invocation quotas - GET
/admin/quotas/addons/{user_id}- Get quota - PUT
/admin/quotas/addons/{user_id}- Update quota - DELETE
/admin/quotas/addons/{user_id}- Delete quota
Admin Settings
These endpoints manage database-stored system settings. All endpoints require administrator privileges.
Endpoints
- GET
/admin/settings- List all system settings - GET
/admin/settings/{key}- Get setting by key - PUT
/admin/settings/{key}- Update setting - DELETE
/admin/settings/{key}- Delete setting - POST
/admin/settings/migrate- Migrate settings from configuration files - POST
/admin/settings/reencrypt- Re-encrypt all settings with current key
SAML Users
For SAML integrations, authenticated users can list other users from the same SAML provider. This is primarily used for UI autocomplete when assigning permissions.
GET /saml/providers/{idp}/users
Authorization: Bearer {token}
Security: You must be authenticated via the same SAML provider you are querying.
API Info
The root endpoint provides service information and health status. TMI does not expose separate /health or /ready endpoints; use GET / instead.
Get API Info
GET /
This endpoint does not require authentication.
Response (200 OK):
{
"status": {
"code": "ok",
"time": "2025-01-15T12:00:00Z"
},
"service": {
"name": "TMI",
"build": "1.4.0-rc.0"
},
"api": {
"version": "1.4.0",
"specification": "https://github.com/ericfitz/tmi/blob/main/api-schema/tmi-openapi.json"
},
"operator": {
"name": "My Organization",
"contact": "[email protected]"
}
}
Status codes: ok (all components healthy), degraded (database or Redis unhealthy), error (critical failure).
When status is degraded, the response includes a health object with component-level details:
{
"health": {
"database": { "status": "healthy", "latency_ms": 5 },
"redis": { "status": "unhealthy", "latency_ms": -1, "message": "Connection refused" }
}
}
The operator field appears only when the server operator has configured it.
Authentication
OAuth2 authentication endpoints. For a high-level overview of authentication, see API-Overview.
List OAuth Providers
GET /oauth2/providers
Initiate OAuth Authorization
GET /oauth2/authorize?provider={provider}
Providers: Configured identity providers (e.g., github, google, microsoft)
Response: Redirects to OAuth provider.
OAuth Callback
GET /oauth2/callback?code={code}&state={state}
Exchange Code for Token
POST /oauth2/token?grant_type=authorization_code&code={code}
Refresh Token
POST /oauth2/refresh
Revoke Token
POST /oauth2/revoke
Token Introspection
POST /oauth2/introspect
Get Current User (OIDC)
GET /oauth2/userinfo
Authorization: Bearer {token}
Returns OIDC-compliant userinfo response with sub, email, name, idp, groups.
Provider Groups
GET /oauth2/providers/{idp}/groups
Authorization: Bearer {token}
SAML
SAML authentication endpoints. For SAML configuration, see Setting-Up-Authentication.
- GET
/saml/providers- List available SAML providers - GET
/saml/{provider}/login- Initiate SAML authentication - GET
/saml/{provider}/metadata- Get SAML SP metadata - POST
/saml/acs- SAML Assertion Consumer Service - GET
/saml/slo- SAML Single Logout (GET) - POST
/saml/slo- SAML Single Logout (POST)
Client Configuration
GET /config
Returns client-side configuration including available identity providers, feature flags, and UI settings. This endpoint does not require authentication.
Well-Known Endpoints
Standard discovery endpoints:
- GET
/.well-known/jwks.json- JSON Web Key Set - GET
/.well-known/oauth-authorization-server- OAuth 2.0 Authorization Server Metadata - GET
/.well-known/oauth-protected-resource- OAuth 2.0 Protected Resource Metadata - GET
/.well-known/openid-configuration- OpenID Connect Discovery
WebSocket Ticket
GET /ws/ticket
Authorization: Bearer {token}
Obtains a short-lived ticket for WebSocket authentication. See WebSocket-API-Reference for full details on establishing WebSocket connections.
Related Documentation
- API-Overview -- API design principles and authentication
- WebSocket-API-Reference -- WebSocket API for real-time collaboration
- API-Workflows -- Common usage patterns and workflow examples
- API-Integration -- Integration guide for third-party systems
- API-Rate-Limiting -- Rate limiting details and client integration
- Webhook-Integration -- Webhook setup and event handling
- Addon-System -- Addon registration and invocation
- API-Specifications -- Complete OpenAPI specification