Management API - Tenant And Features
This page covers tenant-level feature endpoints: Certificate Pinning certificates, custom messages, custom library generation, support tickets, billing helpers, tenant documents, sales contact requests, Tego Assistant, and AI Search.
All endpoints require an authenticated Management API caller and the tenant header unless stated otherwise.
Certificate Pinning Certificates
Certificate Pinning certificate endpoints update the CertificatePinning section of a tenant configuration version. They require the Certificates permission.
Update Certificates
Endpoint: POST /frontend/certificates_update
Permission: update_certificates
Updates the certificate list for one configuration version.
Request:
{
"version": "1.2.3",
"use_builtin_cas": true,
"certificates": [
{
"name": "Example API",
"thumbprint": "A1B2C3D4E5F60718293A4B5C6D7E8F9012345678",
"algorithm": "sha256",
"expires": 1767225600,
"domains": [
"api.example.com"
],
"isdefault": false,
"isca": false
}
]
}
Response:
{
"success": true
}
version must identify an existing tenant configuration version. certificates must be a list of custom certificate entries and can contain up to 50 entries. thumbprint is normalized to uppercase before storage.
Supported algorithms are:
sha1sha224sha256sha384sha512sha3_224sha3_256sha3_384sha3_512
domains may be supplied as a list or a single string. expires is a Unix timestamp.
use_builtin_cas controls whether built-in AppTego CA entries are included in the Certificate Pinning control. Built-in CA details can be inspected with /frontend/trusted_root_cas, documented in Configuration.
Delete Certificate
Endpoint: POST /frontend/certificates_delete
Permission: update_certificates
Deletes one certificate entry by name from a configuration version.
Request:
{
"version": "1.2.3",
"name": "Example API"
}
Response:
{
"success": true
}
Custom Messages
Custom messages are available to Team and Enterprise tenants. Mutating endpoints require the Custom Messages permission.
Custom messages are stored per configuration version. The message body is a string and can be up to 5 MB (5,242,880 UTF-8 bytes), including HTML markup and inline CSS.
Get Custom Message
Endpoint: POST /frontend/get_custom_message
Permission: Any authenticated tenant user on a Team or Enterprise tenant
Request:
{
"version": "1.2.3"
}
Response:
{
"message": "Please contact your administrator.",
"in_use": true
}
When no custom message exists for the version, the response is:
{
"message": "",
"in_use": false
}
Update Custom Message
Endpoint: POST /frontend/update_custom_message
Permission: manage_custom_messages
Request:
{
"version": "1.2.3",
"message": "Please contact your administrator."
}
Response:
{
"success": true
}
Set Custom Message Active State
Endpoint: POST /frontend/set_custom_message_active
Permission: manage_custom_messages
Request:
{
"version": "1.2.3",
"in_use": true
}
Response:
{
"success": true
}
Custom Library / BYOA
Custom Library generation is an Enterprise feature and must be enabled for the tenant. It generates Android and iOS library builds for approved application identifiers.
Get Custom Library Status
Endpoint: POST /frontend/custom_library_status
Permission: Any authenticated tenant user on an Enterprise tenant
Request:
{}
Response when enabled:
{
"enabled": true,
"max_identifiers": 3,
"identifier_count": 1,
"identifiers": [
{
"app_identifier": "com.example.production.app",
"set_at": 1732740000,
"set_by": "owner@example.com",
"platform_cooldowns": {
"android": {
"cooldown_remaining_seconds": 0,
"cooldown_remaining_days": 0
},
"ios": {
"cooldown_remaining_seconds": 0,
"cooldown_remaining_days": 0
}
},
"builds": [
{
"build_id": "build-uuid",
"platform": "android",
"app_identifier": "com.example.production.app",
"status": "success",
"created_at": 1732740000,
"completed_at": 1732740300,
"error_message": null
}
],
"latest_by_platform": {
"android": {
"build_id": "build-uuid",
"platform": "android",
"app_identifier": "com.example.production.app",
"status": "success",
"created_at": 1732740000,
"completed_at": 1732740300,
"error_message": null
}
}
}
]
}
Response when disabled:
{
"enabled": false,
"max_identifiers": 0,
"identifiers": []
}
Build status values include pending, building, success, failed, and deleted.
Set App Identifier
Endpoint: POST /frontend/custom_library_set_identifier
Permission: modify_tenant_settings
Adds an application identifier and starts library-only builds for Android and iOS.
Request:
{
"app_identifier": "com.example.production.app"
}
Response:
{
"message": "App identifier set successfully",
"app_identifier": "com.example.production.app"
}
The identifier must be reverse-DNS style, contain at least three segments, and be no more than 255 characters. Segments must be no more than 63 characters, start with a letter, and cannot use reserved or blocked prefixes such as com.example, com.android, or java.
Download Custom Library
Endpoint: POST /frontend/custom_library_download
Permission: Any authenticated tenant user on an Enterprise tenant
Downloads the latest successful build for a platform, or a specific successful build when build_id is supplied.
Request:
{
"platform": "android",
"build_id": "build-uuid"
}
build_id is optional.
Response:
{
"url": "https://presigned-download-url.example"
}
The returned URL expires after one hour.
Delete Custom Library Identifier
Endpoint: POST /frontend/custom_library_delete
Permission: build_applications
Deletes all custom library builds for an application identifier and removes the identifier record.
Request:
{
"app_identifier": "com.example.production.app"
}
Response:
{
"message": "Libraries for com.example.production.app deleted successfully"
}
Deletion is blocked while any library build for the identifier is pending or building. After a successful build, deletion is also blocked until the platform cooldown has expired. The implemented cooldown is 30 days.
Support Tickets
Support tickets are available for Team and Enterprise tenants. These endpoints do not require a specific tenant permission beyond authenticated tenant access.
Limits:
| Limit | Value |
|---|---|
| Open tickets per tenant | 10 |
| Comments per ticket | 20 |
| Subject length | 200 characters |
| Description length | 5000 characters |
| Comment length | 5000 characters |
| Attachments | PNG or JPEG only, maximum 5 MB decoded size |
Ticket statuses are Reported, With Support, For Customer Response, and Resolved.
List Tickets
Endpoint: GET /frontend/support/tickets
Response:
{
"tickets": [
{
"ticket_id": "ticket-uuid",
"tenant_id": "9f1c0a4e7b8d4a4db52e6a6d5c5c1f11",
"tenant_name": "Example Tenant",
"tenant_plan": "TEAM",
"user_id": "owner@example.com",
"subject": "Build question",
"status": "Reported",
"created_at": 1732740000,
"updated_at": 1732740000
}
]
}
Create Ticket
Endpoint: POST /frontend/support/tickets
Request:
{
"subject": "Build question",
"description": "Can you help us understand this build failure?",
"attachment": "base64-encoded-png-or-jpeg",
"attachment_name": "screenshot.png",
"attachment_type": "image/png"
}
Attachment fields are optional. attachment must be Base64 encoded file content.
Response:
{
"success": true,
"ticket_id": "ticket-uuid"
}
New tickets start with status Reported.
Get Ticket
Endpoint: GET /frontend/support/tickets/{ticket_id}
Response:
{
"ticket_id": "ticket-uuid",
"tenant_id": "9f1c0a4e7b8d4a4db52e6a6d5c5c1f11",
"tenant_name": "Example Tenant",
"tenant_plan": "TEAM",
"user_id": "owner@example.com",
"subject": "Build question",
"description": "Can you help us understand this build failure?",
"status": "Reported",
"created_at": 1732740000,
"updated_at": 1732740000,
"comments": [
{
"comment_id": "comment-uuid",
"user_id": "owner@example.com",
"comment_text": "Here is more context.",
"created_at": 1732740600
}
],
"attachments": [
{
"attachment_id": "attachment-uuid",
"comment_id": null,
"file_name": "screenshot.png",
"file_type": "image/png",
"uploaded_by": "owner@example.com",
"created_at": 1732740000
}
]
}
Add Comment
Endpoint: POST /frontend/support/tickets/{ticket_id}/comments
Request:
{
"comment_text": "Here is more context.",
"attachment": "base64-encoded-png-or-jpeg",
"attachment_name": "screenshot.jpg",
"attachment_type": "image/jpeg"
}
Attachment fields are optional.
Response:
{
"success": true,
"comment_id": "comment-uuid"
}
Download Attachment
Endpoint: GET /frontend/support/attachments/{attachment_id}
Response:
{
"file_name": "screenshot.png",
"file_type": "image/png",
"file_data": "base64-encoded-file-content"
}
Billing Helpers
Billing helper endpoints use Stripe subscription data for the current tenant. Mutating endpoints require Tenant Settings.
Check Subscription
Endpoint: POST /frontend/payment/check-subscription
Permission: Any authenticated tenant user
Request:
{}
Response:
{
"subscription": "active"
}
subscription is active or inactive.
Create Checkout Session
Endpoint: POST /frontend/payment/create-checkout-session
Permission: modify_tenant_settings
Request:
{
"subscription": "team"
}
Response:
{
"url": "https://checkout.stripe.com/..."
}
subscription must match an available Stripe plan key, such as team or enterprise.
Update Subscription
Endpoint: POST /frontend/payment/update-subscription
Permission: modify_tenant_settings
Request:
{
"subscription": "enterprise"
}
Response:
{
"success": true,
"message": "Subscription updated successfully"
}
Cancel Subscription
Endpoint: POST /frontend/payment/cancel-subscription
Permission: modify_tenant_settings
Request:
{}
Response:
{
"success": true,
"message": "Subscription will be cancelled at the end of the billing period"
}
Create Billing Portal Session
Endpoint: POST /frontend/payment/create-portal-session
Permission: modify_tenant_settings
Request:
{}
Response:
{
"url": "https://billing.stripe.com/..."
}
List Invoices
Endpoint: POST /frontend/payment/list-invoices
Permission: modify_tenant_settings
Request:
{}
Response:
{
"invoices": [
{
"id": "in_123",
"number": "ABCD-0001",
"amount_paid": 99.0,
"currency": "USD",
"status": "paid",
"created": 1732740000,
"period_start": 1732740000,
"period_end": 1735332000,
"invoice_pdf": "https://pay.stripe.com/invoice/.../pdf",
"hosted_invoice_url": "https://invoice.stripe.com/..."
}
]
}
Tenant Documents
Tenant document endpoints return standard legal documents and tenant-specific custom documents.
List Documents
Endpoint: GET /frontend/documents
Permission: Any authenticated tenant user
Response:
{
"documents": [
{
"name": "Terms of Service",
"filename": "terms.pdf",
"category": "legal",
"description": "Terms and conditions for using AppTego.",
"base_url": "/documents/legal/team/",
"type": "standard"
},
{
"name": "Security Addendum",
"filename": "security-addendum.pdf",
"category": "custom",
"description": "Tenant-specific document.",
"type": "custom"
}
]
}
Free tenants receive the standard Free-plan legal document list and a base_url for the static files. Paid tenants receive tier-specific standard documents plus any tenant custom documents.
Download Custom Document
Endpoint: GET /frontend/documents/download?filename={filename}
Permission: Any authenticated tenant user on a Team or Enterprise tenant
Response:
{
"url": "https://presigned-download-url.example"
}
The returned URL expires after five minutes. Free-plan standard documents are served directly from the base_url returned by /frontend/documents and do not use this download endpoint.
Sales Contact Requests
Sales contact requests let an authenticated tenant user request AppTego sales follow-up for Team or Enterprise plans. Requests have a seven-day per-user cooldown.
Check Sales Contact Cooldown
Endpoint: GET /frontend/sales_contact/status
Permission: Any authenticated tenant user
Response:
{
"on_cooldown": false,
"cooldown_until": null
}
Request Sales Contact
Endpoint: POST /frontend/sales_contact/request
Permission: Any authenticated tenant user
Request:
{
"tier": "ENTERPRISE"
}
tier must be TEAM or ENTERPRISE.
Response:
{
"message": "We'll contact you shortly.",
"on_cooldown": true,
"cooldown_until": 1733344800
}
When the user is still on cooldown, the endpoint returns 429 with on_cooldown and cooldown_until.
Tego Assistant
Tego Assistant endpoints are available on all plans. Default weekly tenant limits are 10 messages for Free, 100 for Team, and 1000 for Enterprise. Tenant-specific overrides may apply.
The response still includes a monthly_limit field for compatibility; it mirrors the active weekly limit.
Send Message
Endpoint: POST /frontend/helpbot/chat
Permission: Any authenticated tenant user
Request:
{
"message": "How do I configure Certificate Pinning?"
}
Messages must be 2000 characters or less.
Response:
{
"response": "Certificate Pinning is configured from the configuration controls...",
"phases": [
{
"expert": "Tego",
"status": "Analysing your question..."
},
{
"expert": "Tego",
"status": "Preparing your answer..."
}
],
"messages_used": 4,
"weekly_limit": 100,
"monthly_limit": 100,
"allowed_again_at": 1733097600,
"allowed_again_at_utc": "2024-12-02T00:00:00Z"
}
When the weekly limit is reached, the endpoint returns 429 with weekly_limit, monthly_limit, messages_used, allowed_again_at, and allowed_again_at_utc.
Get Conversation History
Endpoint: GET /frontend/helpbot/history
Response:
{
"messages": [
{
"role": "user",
"content": "How do I configure Certificate Pinning?"
},
{
"role": "assistant",
"content": "Certificate Pinning is configured from the configuration controls..."
}
]
}
Clear Conversation History
Endpoint: POST /frontend/helpbot/clear
Response:
{
"success": true
}
Get Usage Status
Endpoint: GET /frontend/helpbot/status
Response:
{
"weekly_limit": 100,
"monthly_limit": 100,
"messages_used": 4,
"messages_remaining": 96,
"allowed_again_at": 1733097600,
"allowed_again_at_utc": "2024-12-02T00:00:00Z"
}
AI Search
AI Search converts natural language into query and time-window parameters for audit and device log searches. It does not return log rows directly.
AI Search is available for Team and Enterprise tenants. Monthly tenant limits are 100 queries for Team and 200 for Enterprise.
Convert Natural Language Query
Endpoint: POST /frontend/nl_search_query
Permission: Any authenticated tenant user on a Team or Enterprise tenant
Request:
{
"mode": "audit",
"query": "configuration changes from last week"
}
mode must be audit or device. query must be 500 characters or less.
Response:
{
"query": "event_type = 'configuration_change'",
"from_iso": "2024-11-18T00:00:00Z",
"to_iso": "2024-11-25T00:00:00Z",
"usage": {
"used": 12,
"limit": 100
}
}
Use the returned query, from_iso, and to_iso values with the relevant log search endpoint in Monitoring and Logs. The endpoint may return 422 when the model cannot interpret the query reliably.
Common Errors
| Status | Meaning |
|---|---|
400 | Missing field, invalid field value, unsupported file type, exceeded feature limit, or blocked operation such as an active custom library cooldown. |
401 | Authentication failed. |
403 | Missing permission, missing feature enablement, or plan-gated feature. |
404 | Requested ticket, attachment, document, custom library build, or identifier was not found. |
409 | Custom library deletion was blocked by an in-progress build. |
422 | AI Search could not interpret the natural language query. |
429 | Tego Assistant limit or sales contact cooldown reached. |
500 | Internal error. |