openapi: 3.0.3 info: title: Gigstack API v2 description: | # gigstack API v2 Comprehensive API for invoice, payment, client, and service management with **Mexican tax compliance (SAT)**. ## 🚀 Getting Started 1. **Get your token** at [app.gigstack.pro/settings?tab=api](https://app.gigstack.pro/settings?tab=api) 2. **Include in header:** `Authorization: Bearer YOUR_TOKEN` 3. **Base URL:** `https://api.gigstack.io/v2` ## 📋 Key Features - **Mexican Tax Compliance** (SAT, RFC, CFDI) - **Full Invoice Lifecycle** (creation, stamping, cancellation) - **Payment Processing** (multiple processors, refunds) - **Client Management** (fiscal validation, EFOS) - **Service Catalog** (products with tax configurations) - **Team & User Management** ## 📄 Response Format All successful responses follow this format: ```json { "message": "Description of action", "data": {} // Response data } ``` List responses include pagination: ```json { "message": "Items retrieved successfully", "data": [...], "next": "cursor_for_next_page", "has_more": true, "total_results": 150 } ``` Error responses use this format: ```json { "message": "Error description", "error": "Specific error details" } ``` ## 🔒 Authentication **Simple Bearer Token Authentication** All endpoints require ONLY a Bearer token in the Authorization header: ``` Authorization: Bearer YOUR_TOKEN ``` **No additional authentication required:** - ❌ No private keys needed - ❌ No payload signatures required - ❌ No additional headers needed - ✅ Just the Authorization header with your Bearer token **Important:** The `team` and `livemode` parameters are automatically extracted from your JWT token and applied to all requests. You do not need to include these fields in request bodies - they are handled automatically by the API. ## 🔗 gigstack Connect gigstack Connect allows authorized teams to access resources across multiple teams within the same billing account. ### How to Use gigstack Connect Add the `team` query parameter to **ANY ENDPOINT** to access another team's resources: ```bash # Access team_xyz789's clients GET /clients?team=team_xyz789&limit=10 # Create invoice for team_abc123 POST /invoices?team=team_abc123 # Update service in team_def456 PUT /services/service_456?team=team_def456 ``` ### Requirements - Your API key must belong to a team with gigstack Connect enabled - Target team must share the same billing account - Target team must exist ### Error Responses - `401 Unauthorized, not a master team` - Your team doesn't have gigstack Connect enabled - `404 Team not found` - Target team doesn't exist - `401 Unauthorized, no matched teams` - Teams don't share the same billing account ### Global Availability The `team` parameter is available on **ALL 35+ endpoints** in this API for seamless multi-team management. ## 📚 Common Use Cases - **Create Invoice:** `POST /invoices` with client and items - **Process Payment:** `POST /payments` then `POST /payments/{id}/paid` - **Manage Clients:** `POST /clients` with fiscal information - **SAT Compliance:** Use proper tax codes and validation - **gigstack Connect:** Use `?team=target_team_id` for multi-team management ## đŸ“± iOS & Mobile Development ### Swift Integration The gigstack API is fully compatible with iOS development using URLSession or networking libraries like Alamofire. **Basic Swift Example:** ```swift import Foundation struct GigstackAPI { static let baseURL = "https://api.gigstack.io/v2" static let token = "YOUR_BEARER_TOKEN" static func makeRequest( endpoint: String, method: String = "GET", body: [String: Any]? = nil, responseType: T.Type ) async throws -> T { var request = URLRequest(url: URL(string: "\(baseURL)\(endpoint)")!) request.httpMethod = method request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") request.setValue("application/json", forHTTPHeaderField: "Content-Type") if let body = body { request.httpBody = try JSONSerialization.data(withJSONObject: body) } let (data, _) = try await URLSession.shared.data(for: request) return try JSONDecoder().decode(responseType, from: data) } } ``` ### Key iOS Considerations - **HTTPS Only**: All requests must use HTTPS (already enforced) - **JSON Content-Type**: Always set `Content-Type: application/json` - **Authorization Header**: Include `Authorization: Bearer YOUR_TOKEN` - **Error Handling**: Parse JSON error responses for user-friendly messages - **Networking**: Compatible with URLSession, Alamofire, or any HTTP client - **Background Tasks**: API calls work with background URL sessions ### iOS Response Models Create Codable structs matching the API response schemas: ```swift struct APIResponse: Codable { let message: String let data: T let next: String? let hasMore: Bool? let totalResults: Int? enum CodingKeys: String, CodingKey { case message, data, next case hasMore = "has_more" case totalResults = "total_results" } } struct Client: Codable { let id: String let name: String? let email: String? let company: String? let taxId: String? let createdAt: Int enum CodingKeys: String, CodingKey { case id, name, email, company case taxId = "tax_id" case createdAt = "created_at" } } ``` ### Android/Kotlin Integration **Basic Kotlin Example with OkHttp:** ```kotlin import okhttp3.* import kotlinx.serialization.json.Json import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext class GigstackAPI { companion object { private const val BASE_URL = "https://api.gigstack.io/v2" private const val TOKEN = "YOUR_BEARER_TOKEN" private val client = OkHttpClient() private val json = Json { ignoreUnknownKeys = true } } suspend fun makeRequest( endpoint: String, method: String = "GET", body: RequestBody? = null, responseClass: Class ): T = withContext(Dispatchers.IO) { val request = Request.Builder() .url("$BASE_URL$endpoint") .method(method, body) .addHeader("Authorization", "Bearer $TOKEN") .addHeader("Content-Type", "application/json") .build() val response = client.newCall(request).execute() val responseBody = response.body?.string() ?: "" json.decodeFromString(responseClass, responseBody) } } ``` version: 2.0.0 contact: name: Gigstack API Support url: https://gigstack.io email: support@gigstack.io license: name: Proprietary url: https://gigstack.io/terms termsOfService: https://gigstack.io/terms servers: - url: https://api.gigstack.io/v2 description: Production API - url: https://api.gigstack.io/v2 description: Staging API (use test API key for staging environment) externalDocs: description: Complete API Documentation & Guides url: https://docs.gigstack.io security: - apiKey: [] components: securitySchemes: apiKey: type: apiKey in: header name: Authorization description: | **Authentication Method:** API Key in Authorization Header Include your JWT token in the Authorization header with Bearer prefix. **Header Format:** `Authorization: Bearer YOUR_JWT_TOKEN` **Example:** `Authorization: Bearer eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJSUzI1NiJ9...` **Get your token at:** [app.gigstack.pro/settings?tab=api](https://app.gigstack.pro/settings?tab=api) **Note:** Only the Authorization header with your JWT token is required. Include the "Bearer " prefix before your token. parameters: TeamParameter: name: team in: query schema: type: string description: | **gigstack Connect:** Target team ID for multi-team access. Requires gigstack Connect enabled on your team and shared billing account. **Example:** `?team=team_xyz789` LimitParam: name: limit in: query description: Maximum number of items to return (default 50, max 100) required: false schema: type: integer minimum: 1 maximum: 100 default: 50 NextParam: name: next in: query description: Pagination cursor for the next page of results required: false schema: type: string nullable: true # Sorting parameters OrderByParam: name: order_by in: query description: Field name to order results by required: false schema: type: string enum: ['name', 'timestamp'] default: 'timestamp' SortParam: name: sort in: query description: Sort direction for the results required: false schema: $ref: '#/components/schemas/OrderDirection' # Filtering parameters - Date range filters (use Unix timestamps in seconds or ISO 8601 date strings) CreatedGteParam: name: created[gte] in: query description: Filter results created on or after this timestamp. Accepts Unix timestamp in seconds (e.g., 1733011200), milliseconds (e.g., 1733011200000), or ISO 8601 date string (e.g., 2024-12-01). required: false schema: oneOf: - type: integer format: int64 - type: string format: date example: 1733011200 CreatedGtParam: name: created[gt] in: query description: Filter results created after this timestamp. Accepts Unix timestamp in seconds (e.g., 1733011200), milliseconds (e.g., 1733011200000), or ISO 8601 date string (e.g., 2024-12-01). required: false schema: oneOf: - type: integer format: int64 - type: string format: date example: 1733011200 CreatedLteParam: name: created[lte] in: query description: Filter results created on or before this timestamp. Accepts Unix timestamp in seconds (e.g., 1735689599), milliseconds (e.g., 1735689599000), or ISO 8601 date string (e.g., 2024-12-31). required: false schema: oneOf: - type: integer format: int64 - type: string format: date example: 1735689599 CreatedLtParam: name: created[lt] in: query description: Filter results created before this timestamp. Accepts Unix timestamp in seconds (e.g., 1735689599), milliseconds (e.g., 1735689599000), or ISO 8601 date string (e.g., 2024-12-31). required: false schema: oneOf: - type: integer format: int64 - type: string format: date example: 1735689599 FieldsParam: name: fields in: query description: Comma-separated list of fields to include in the response required: false style: form explode: false schema: type: array items: type: string example: 'id,description,created_at' # Payment-specific filter parameters PaymentStatusParam: name: status in: query description: Filter payments by status required: false schema: type: string enum: [requires_payment_method, succeeded, canceled] PaymentCurrencyParam: name: currency in: query description: Filter payments by currency code (e.g., MXN, USD) required: false schema: type: string PaymentClientIdParam: name: client_id in: query description: Filter payments by client ID required: false schema: type: string PaymentEmailParam: name: email in: query description: Filter payments by client email address required: false schema: type: string PaymentTaxIdParam: name: tax_id in: query description: Filter payments by client tax ID (RFC) required: false schema: type: string PaymentClientNameParam: name: client_name in: query description: Filter payments by client name required: false schema: type: string PaymentAmountParam: name: amount in: query description: Filter payments by amount required: false schema: type: number # Search-specific parameters SearchQueryParam: name: q in: query description: | Search query text (primary parameter). Searches across relevant fields depending on the collection (e.g., client name, email, payment ID, description, metadata). The `query` parameter is also accepted as a backward-compatible alternative. required: true schema: type: string SearchQueryBackwardCompatParam: name: query in: query description: Alternative to `q`, kept for backward compatibility. If both are provided, `q` takes precedence. required: false schema: type: string SearchPageParam: name: page in: query description: Page number for pagination (default 1) required: false schema: type: integer minimum: 1 default: 1 schemas: OrderDirection: type: string enum: [asc, desc] description: Sort direction for list queries # Common response wrapper for list endpoints ListQueryParams: type: object description: Common query parameters for list endpoints properties: limit: type: integer minimum: 1 maximum: 100 default: 50 next: type: string nullable: true order_by: type: string enum: ['name', 'timestamp'] default: 'timestamp' sort: $ref: '#/components/schemas/OrderDirection' gte: type: integer format: int64 description: Filter results created on or after this Unix timestamp (seconds) lte: type: integer format: int64 description: Filter results created on or before this Unix timestamp (seconds) gt: type: integer format: int64 description: Filter results created after this Unix timestamp (seconds) lt: type: integer format: int64 description: Filter results created before this Unix timestamp (seconds) query: type: string fields: type: array items: type: string # Pagination metadata for responses PaginationMeta: type: object required: [limit, has_more] properties: limit: type: integer description: Number of items per page has_more: type: boolean description: Whether there are more items available next: type: string nullable: true description: Cursor for the next page (null if no more pages) total: type: integer nullable: true description: Total number of items (may be null for performance reasons) # API Response Schemas ApiPublicClient: type: object required: - id - email - from - livemode - owner - team - created_at properties: id: type: string example: 'client_1234567890' description: 'Unique client identifier' address: $ref: '#/components/schemas/ClientAddress' name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' description: 'Client name' company: type: string nullable: true example: 'Empresa SA de CV' description: 'Client company name' phone: type: string nullable: true example: '+52 55 1234 5678' description: 'Client phone number' email: type: string format: email nullable: true example: 'juan.perez@ejemplo.com' description: 'Client email address' bcc: type: array items: type: string format: email nullable: true example: ['admin@empresa.com'] description: 'BCC email addresses for client communications' metadata: type: object additionalProperties: true nullable: true example: { 'custom_field': 'value' } description: 'Additional metadata for the client' is_valid: type: boolean nullable: true example: true description: 'Whether the client data is valid' from: type: string example: 'api' description: 'Source of client creation' legal_name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' description: 'Legal name for tax purposes' livemode: type: boolean example: true description: 'Whether this client is in live mode' owner: type: string example: 'user_1234567890' description: 'User ID who owns this client' tax_id: type: string nullable: true example: 'PEGJ800101ABC' description: 'RFC (Tax ID) for Mexican tax compliance' use: type: string nullable: true example: 'P01' description: 'CFDI use code' tax_system: type: string nullable: true example: '601' description: 'SAT tax system code' team: type: string example: 'team_1234567890' description: 'Team ID this client belongs to' created_at: type: number example: 1677651234 description: 'Unix timestamp of client creation' efos: type: object nullable: true properties: is_valid: type: boolean nullable: true example: true description: 'Whether the client is valid according to SAT EFOS list' description: 'EFOS (SAT blacklist) validation status' defaults: type: object nullable: true properties: keep_full_legal_name: type: boolean nullable: true example: false description: 'Keep full legal name in documents' issue_automatic_invoices: type: boolean nullable: true example: false description: 'Issue automatic invoices' issue_invoiceable_receipts: type: boolean nullable: true example: true description: 'Issue invoiceable receipts' description: 'Client default settings' # Legacy alias for backward compatibility Client: $ref: '#/components/schemas/ApiPublicClient' ApiPublicService: type: object required: - team - created_at properties: id: type: string nullable: true example: 'service_1234567890' description: 'Unique service identifier' description: type: string nullable: true example: 'Consulting services' description: 'Service description' from: type: string nullable: true example: 'api' description: 'Source of service creation' sku: type: string nullable: true example: 'CONS-001' description: 'Stock Keeping Unit identifier' product_key: type: string nullable: true example: '80141503' description: 'SAT product key for tax compliance' unit_key: type: string nullable: true example: 'E48' description: 'SAT unit key for tax compliance' unit_name: type: string nullable: true example: 'Servicio' description: 'Unit name for the service' unit_price: type: number nullable: true example: 1000.00 description: 'Price per unit' taxes: type: array items: $ref: '#/components/schemas/TaxElement' nullable: true description: 'Tax configuration for this service' team: type: string example: 'team_1234567890' description: 'Team ID this service belongs to' created_at: type: number example: 1677651234 description: 'Unix timestamp of service creation' quantity: type: number nullable: true example: 1 description: 'Quantity (used in transactions)' # Legacy alias for backward compatibility Service: $ref: '#/components/schemas/ApiPublicService' ClientInput: type: object required: - name - email properties: address: type: object nullable: true properties: country: type: string nullable: true example: 'MEX' street: type: string nullable: true example: 'Av. Insurgentes Sur' zip: type: string nullable: true example: '03100' city: type: string nullable: true example: 'Ciudad de MĂ©xico' state: type: string nullable: true example: 'CDMX' exterior: type: string nullable: true example: '123' interior: type: string nullable: true example: '4B' municipality: type: string nullable: true example: 'Benito JuĂĄrez' neighborhood: type: string nullable: true example: 'Del Valle' name: type: string example: 'Juan PĂ©rez GarcĂ­a' company: type: string nullable: true example: 'Empresa SA de CV' phone: type: string nullable: true example: '+52 55 1234 5678' email: type: string format: email nullable: true example: 'juan.perez@ejemplo.com' bcc: type: array items: type: string format: email example: ['admin@empresa.com'] metadata: type: object nullable: true additionalProperties: true example: { 'custom_field': 'value' } legal_name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' tax_id: type: string nullable: true example: 'PEGJ800101ABC' use: type: string nullable: true example: 'P01' tax_system: type: string nullable: true example: '601' defaults: type: object properties: keep_full_legal_name: type: boolean example: false issue_automatic_invoices: type: boolean example: false issue_invoiceable_receipts: type: boolean example: true search: type: object nullable: true description: | Search for an existing client before creating. If a match is found, the existing client is returned (or updated if `update: true`). This enables upsert-like behavior to avoid duplicate clients. properties: on_key: type: string description: The field to search on (e.g., 'tax_id', 'email', 'name') example: 'tax_id' on_value: type: string description: The value to match against the specified field example: 'PEGJ800101ABC' update: type: boolean description: If true and a match is found, update the existing client with the provided data. If false, return the existing client without modifications. example: false ServiceInput: type: object properties: description: type: string nullable: true example: 'Consulting services' sku: type: string nullable: true example: 'CONS-001' product_key: type: string nullable: true example: '80141503' unit_key: type: string nullable: true example: 'E48' unit_name: type: string nullable: true example: 'Servicio' unit_price: type: number nullable: true example: 1000.00 taxes: type: array items: type: object properties: base: oneOf: - type: number - type: string nullable: true description: 'Taxable base amount. Accepts number or numeric string. If null, calculated automatically from item price.' example: 100 factor: type: string nullable: true example: 'Tasa' inclusive: type: boolean nullable: true example: false rate: type: number nullable: true example: 0.16 type: type: string enum: ['IVA', 'ISR', 'IEPS'] nullable: true example: 'IVA' withholding: type: boolean nullable: true example: false # CFDI Error Schemas CfdiError: type: object required: - code - description - explanation - solution - type properties: code: type: string description: Unique CFDI error code identifier example: CFDI140223 description: type: string description: Brief description of the error (typically in Spanish as provided by SAT) example: El campo Rfc del receptor no es valido explanation: type: string description: Detailed explanation of why this error occurs example: The RFC (tax ID) provided for the receiver does not meet the validation requirements or format specified by SAT solution: type: string description: Actionable steps to resolve the error example: Verify that the receiver's RFC is correct, properly formatted (13 characters for individuals, 12 for legal entities), and matches SAT's registered information type: type: string enum: - invoice - receiver - sender - unknown description: Category of the error example: receiver # Invoice Schemas Invoice: type: object properties: uuid: type: string example: 'invoice_1234567890' description: 'Unique invoice identifier' idempotency_key: type: string nullable: true example: 'unique_key_123' description: 'Idempotency key used when creating the invoice' client: $ref: '#/components/schemas/ApiPublicClient' created_at: type: number example: 1677651234 description: 'Unix timestamp of invoice creation' currency: type: string example: 'MXN' description: 'Currency code' exchange_rate: type: number example: 1.0 description: 'Exchange rate used' total: type: number example: 1160.00 description: 'Total invoice amount including taxes' subtotal: type: number example: 1000.00 description: 'Subtotal before taxes' discount: type: number example: 0 description: 'Discount amount' taxes: type: number example: 160.00 description: 'Total taxes amount' withholding_taxes: type: number example: 0 description: 'Total withholding taxes amount' series: type: string nullable: true example: 'A' description: 'Invoice series' folio_number: type: number example: 123 description: 'Invoice folio number' invoice_type: type: string enum: ['I', 'E', 'P', 'N'] example: 'I' description: 'Invoice type (I=Ingreso, E=Egreso, P=Pago, N=Nomina)' use: type: string example: 'P01' description: 'CFDI use code' payment_form: type: string example: '03' description: 'SAT payment form code' payment_method: type: string example: 'PUE' description: 'Payment method (PUE/PPD)' payment_conditions: type: string example: '' description: 'Payment conditions' livemode: type: boolean example: true description: 'Whether this invoice is in live mode' owner: type: string example: 'user_1234567890' description: 'User ID who owns this invoice' from: type: string example: 'api' description: 'Source of invoice creation' status: type: string example: 'valid' description: 'Invoice status' payments: type: array items: type: string example: ['payment_1234567890'] description: 'Associated payment IDs' invoices: type: array items: type: string example: [] description: 'Related invoice IDs' addenda: type: string example: '' description: 'Additional XML addenda' exports: type: string example: '01' description: 'Export type code' invoice_pdf_notes: type: string example: '' description: 'Additional notes for PDF' global: type: object nullable: true properties: periodicity: type: string example: '04' months: type: string example: '01' year: type: number example: 2024 description: 'Global invoice configuration' related_documents: type: array items: type: object properties: relationship: type: string example: '04' documents: type: array items: type: string example: ['12345678-1234-1234-1234-123456789012'] description: 'Related documents information' complements: type: array items: type: object properties: type: type: string example: 'custom' data: type: string example: '...' description: 'CFDI complements' cancellation: type: object nullable: true properties: cancelled_at: type: number example: 1677651234 requested_by: type: string example: '' cancellation_receipt: type: string example: '' cancellation_status: type: string example: 'accepted' cancellation_type: type: string example: 'cancellation' code: type: string example: '201' last_checked: type: number example: 1677651234 motive: type: string example: '02' requested_at: type: number example: 1677651234 substitution_uuid: type: string example: '' description: 'Cancellation information' stamp: type: object nullable: true properties: sello: type: string example: 'ABC123...' stamp_at: type: number example: 1677651234 description: 'Stamp information' items: type: array items: type: object properties: id: type: string example: 'item_123' taxability: type: string enum: ['01', '02', '03', '04', '05', '06', '07', '08'] example: '02' taxes: type: array items: $ref: '#/components/schemas/TaxElement' description: type: string example: 'Consulting services' product_key: type: string example: '80141503' quantity: type: number example: 1 sku: type: string example: 'CONS-001' unit_price: type: number example: 1000.00 unit_key: type: string example: 'E48' unit_name: type: string example: 'Servicio' customs_request: type: string nullable: true example: null complement: type: string nullable: true example: null property_tax_account: type: string nullable: true example: null third_party: $ref: '#/components/schemas/ApiPublicThirdParty' description: 'Invoice items' automations: type: array items: $ref: '#/components/schemas/ApiPublicAutomations' nullable: true description: 'Automation configurations' namespaces: type: array items: type: string nullable: true description: 'Namespace configurations' verification_url: type: string example: '' description: 'SAT verification URL' automation: $ref: '#/components/schemas/AutomationTypeEnum' nullable: true description: 'Primary automation type for this invoice' export_classification: type: string nullable: true example: '01' description: 'Export classification code for international transactions' InvoiceIncomeInput: type: object required: - automation_type - client - currency - items - use - payment_form - payment_method properties: automation_type: type: string enum: ['payment', 'none'] example: 'payment' description: | Invoice automation type: - `payment`: Create invoice with payment automation - `none`: No automation, create invoice only client_id: type: string nullable: true example: 'client_1234567890' description: 'Optional client ID, if provided will use this client instead of creating/searching' client: type: object properties: id: type: string example: 'client_1234567890' search: type: object properties: on_key: type: string example: 'tax_id' on_value: type: string example: 'PEGJ800101ABC' auto_create: type: boolean example: true address: $ref: '#/components/schemas/ClientAddress' name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' company: type: string nullable: true example: 'Empresa SA de CV' phone: type: string nullable: true example: '+52 55 1234 5678' email: type: string format: email nullable: true example: 'juan.perez@ejemplo.com' bcc: type: array items: type: string format: email metadata: type: object additionalProperties: true legal_name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' tax_id: type: string nullable: true example: 'PEGJ800101ABC' use: type: string nullable: true example: 'P01' tax_system: type: string nullable: true example: '601' complements: type: array items: type: object properties: type: type: string example: 'custom' data: type: string example: '...' currency: type: string example: 'MXN' exchange_rate: type: number nullable: true example: 1.0 description: 'Exchange rate for currency conversion. If not provided, the latest rate from our rates collection will be used automatically.' folio_number: type: number example: 123 series: type: string example: 'A' idempotency_key: type: string nullable: true example: 'unique_key_123' description: 'Optional idempotency key to prevent duplicate invoices' items: type: array items: type: object properties: id: type: string example: 'service_1234567890' search: type: object properties: on_key: type: string example: 'sku' on_value: type: string example: 'CONS-001' auto_create: type: boolean example: true description: type: string nullable: true example: 'Consulting services' sku: type: string nullable: true example: 'CONS-001' product_key: type: string nullable: true example: '80141503' unit_key: type: string nullable: true example: 'E48' unit_name: type: string nullable: true example: 'Servicio' unit_price: type: number nullable: true example: 1000.00 taxes: type: array items: $ref: '#/components/schemas/TaxSchema' taxability: type: string enum: ['01', '02', '03', '04', '05', '06', '07', '08'] example: '02' third_party: type: object properties: tax_system: type: string example: '601' legal_name: type: string example: 'Third Party SA' zip: type: string example: '03100' tax_id: type: string example: 'TPR800101ABC' use: type: string example: 'P01' related_documents: type: array items: type: object properties: relationship: type: string example: '04' documents: type: array items: type: string example: '12345678-1234-1234-1234-123456789012' global: type: object properties: periodicity: type: string example: '04' months: type: string example: '01' year: type: integer example: 2024 exports: type: string enum: ['01', '02', '03', '04'] example: '01' payment_form: type: string example: '03' payment_method: type: string example: 'PUE' invoice_pdf_notes: type: string example: 'Additional notes for PDF' addenda: type: string example: '...' return_files: type: boolean example: true description: 'Return base64 encoded PDF and XML files in response' metadata: type: object additionalProperties: true send_email: type: boolean example: true emails: type: array items: type: string format: email example: ['client@example.com'] InvoiceEgressInput: type: object required: - client - currency - items - use - payment_form properties: automation_type: type: string enum: ['none'] example: 'none' description: | Payment automation type: - `none`: No automation, create invoice only client_id: type: string nullable: true example: 'client_1234567890' description: 'Optional client ID, if provided will use this client instead of creating/searching' client: type: object properties: id: type: string example: 'client_1234567890' search: type: object properties: on_key: type: string example: 'tax_id' on_value: type: string example: 'PEGJ800101ABC' auto_create: type: boolean example: true address: $ref: '#/components/schemas/ClientAddress' name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' company: type: string nullable: true example: 'Empresa SA de CV' phone: type: string nullable: true example: '+52 55 1234 5678' email: type: string format: email nullable: true example: 'juan.perez@ejemplo.com' bcc: type: array items: type: string format: email metadata: type: object additionalProperties: true legal_name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' tax_id: type: string nullable: true example: 'PEGJ800101ABC' use: type: string nullable: true example: 'P01' tax_system: type: string nullable: true example: '601' complements: type: array items: type: object properties: type: type: string example: 'custom' data: type: string example: '...' currency: type: string example: 'MXN' exchange_rate: type: number nullable: true example: 1.0 description: 'Exchange rate for currency conversion. If not provided, the latest rate from our rates collection will be used automatically.' folio_number: type: number example: 123 series: type: string example: 'A' idempotency_key: type: string nullable: true example: 'unique_key_123' description: 'Optional idempotency key to prevent duplicate invoices' items: type: array items: type: object required: - quantity properties: id: type: string example: 'service_1234567890' search: type: object properties: on_key: type: string example: 'sku' on_value: type: string example: 'CONS-001' auto_create: type: boolean example: true description: type: string nullable: true example: 'Purchased materials' sku: type: string nullable: true example: 'MAT-001' product_key: type: string nullable: true example: '80141503' unit_key: type: string nullable: true example: 'E48' unit_name: type: string nullable: true example: 'Unidad' unit_price: type: number nullable: true example: 500.00 taxes: type: array items: $ref: '#/components/schemas/TaxSchema' taxability: type: string enum: ['01', '02', '03', '04', '05', '06', '07', '08'] example: '02' third_party: type: object properties: tax_system: type: string example: '601' legal_name: type: string example: 'Third Party SA' zip: type: string example: '03100' tax_id: type: string example: 'TPR800101ABC' use: type: string example: 'P01' related_documents: type: array items: type: object properties: relationship: type: string example: '04' documents: type: array items: type: string example: '12345678-1234-1234-1234-123456789012' global: type: object properties: periodicity: type: string example: '04' months: type: string example: '01' year: type: integer example: 2024 exports: type: string enum: ['01', '02', '03', '04'] example: '01' payment_form: type: string example: '03' invoice_pdf_notes: type: string example: 'Additional notes for PDF' addenda: type: string example: '...' return_files: type: boolean example: true description: 'Return base64 encoded PDF and XML files in response' metadata: type: object additionalProperties: true date: type: number example: 1640995200 description: 'Unix timestamp for invoice date' send_emails: type: boolean example: true emails: type: array items: type: string format: email example: ['client@example.com'] # Comprehensive Invoice Input Schema InvoiceInput: type: object required: - client - currency - items - invoice_type - use - payment_form - payment_method properties: client: type: object properties: id: type: string nullable: true example: 'client_1234567890' description: 'Existing client ID' search: type: object properties: on_key: type: string example: 'tax_id' description: 'Field to search client on' on_value: type: string example: 'PEGJ800101ABC' description: 'Value to search for' auto_create: type: boolean example: true description: 'Create client if not found' safety_check: type: boolean example: false description: 'When true, prevents using multiple matching results (returns error). When false, uses the first result found. Default: false' address: $ref: '#/components/schemas/ClientAddress' name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' company: type: string nullable: true example: 'Empresa SA de CV' phone: type: string nullable: true example: '+52 55 1234 5678' email: type: string format: email nullable: true example: 'juan.perez@ejemplo.com' bcc: type: array items: type: string format: email description: 'BCC recipients for invoice emails' legal_name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' tax_id: type: string nullable: true example: 'PEGJ800101ABC' use: type: string nullable: true example: 'P01' tax_system: type: string nullable: true example: '601' metadata: type: object additionalProperties: true automation: $ref: '#/components/schemas/AutomationTypeEnum' nullable: true description: 'Automation type for this invoice' currency: type: string example: 'MXN' description: 'Currency code (ISO 4217)' exchange_rate: type: number nullable: true example: 1.0 description: 'Exchange rate to use for currency conversion' items: type: array items: $ref: '#/components/schemas/ItemSchema' description: 'Invoice items with full tax and third-party support' invoice_type: type: string enum: ['I', 'E', 'P', 'N'] example: 'I' description: | Invoice type: - `I`: Ingreso (Income) - `E`: Egreso (Expense/Credit note) - `P`: Pago (Payment) - `N`: Nomina (Payroll) use: type: string example: 'P01' description: 'CFDI use code (c_UsoCFDI)' payment_form: $ref: '#/components/schemas/PaymentFormEnum' description: 'SAT payment form code' payment_method: type: string enum: ['PUE', 'PPD'] example: 'PUE' description: | Payment method: - `PUE`: Pago en Una ExhibiciĂłn (Immediate payment) - `PPD`: Pago en Parcialidades o Diferido (Deferred payment) payment_conditions: type: string nullable: true example: '' description: 'Payment conditions text' export_classification: type: string nullable: true example: '01' description: 'Export classification for international transactions' global: type: object nullable: true properties: periodicity: type: string example: '04' description: 'Global invoice periodicity' months: type: string example: '01' description: 'Months covered' year: type: number example: 2024 description: 'Year covered' description: 'Global invoice configuration for periodic invoices' series: type: string nullable: true example: 'A' description: 'Invoice series' folio: type: string nullable: true example: '123' description: 'Invoice folio number' addenda: type: string nullable: true example: '' description: 'Additional XML addenda' invoice_pdf_notes: type: string nullable: true example: '' description: 'Additional notes for PDF generation' related_documents: type: array nullable: true items: type: object properties: relationship: type: string example: '04' description: 'Type of relationship' documents: type: array items: type: string example: ['12345678-1234-1234-1234-123456789012'] description: 'Related document UUIDs' description: 'Related documents (for replacements, cancellations, etc.)' complements: type: array nullable: true items: type: object properties: type: type: string example: 'custom' data: type: string example: '...' description: 'CFDI complements (additional XML data)' send_email: type: boolean nullable: true example: true description: 'Whether to send invoice via email' emails: type: array nullable: true items: type: string format: email example: ['client@example.com'] description: 'Additional email recipients' metadata: type: object nullable: true additionalProperties: true description: 'Additional metadata' idempotency_key: type: string nullable: true example: 'invoice-key-12345' description: 'Unique key to prevent duplicate invoices' # Payment Schemas PaymentItem: allOf: - $ref: '#/components/schemas/ApiPublicService' - type: object properties: third_party: $ref: '#/components/schemas/ApiPublicThirdParty' search: $ref: '#/components/schemas/ApiPublicSearch' PaymentAllowedMethod: type: object required: - id properties: id: type: string example: 'card' description: 'Payment method identifier' ApiPublicPaymentProcessorDetails: type: object additionalProperties: type: object properties: payment_intent: type: string example: 'pi_1234567890' description: 'Payment processor intent ID' charge: type: string example: 'ch_1234567890' description: 'Payment processor charge ID' invoice: type: string example: 'in_1234567890' description: 'Payment processor invoice ID' example: stripe: payment_intent: 'pi_1234567890' charge: 'ch_1234567890' invoice: 'in_1234567890' ApiPublicPayment: type: object required: - id - client - currency - exchange_rate - items - team - idempotency_key - from - invoices - livemode - owner - payment_form - payments - receipts - refunds - short_url - status - total - total_refunded - subtotal - taxes - discount - withholding_taxes - created_at - succeeded_at - payment_processor properties: id: type: string example: 'payment_1234567890' description: 'Unique payment identifier' client: $ref: '#/components/schemas/ApiPublicClient' emails: type: array items: type: string format: email nullable: true example: ['client@example.com'] description: 'Email addresses to notify' currency: type: string example: 'MXN' description: 'Payment currency' allowed_payment_methods: type: array items: $ref: '#/components/schemas/PaymentAllowedMethod' nullable: true description: 'Allowed payment methods' exchange_rate: type: number example: 1.0 description: 'Exchange rate used for currency conversion' items: type: array items: $ref: '#/components/schemas/PaymentItem' description: 'Items included in this payment' metadata: type: object additionalProperties: type: string example: { 'order_id': '12345' } description: 'Additional metadata for the payment' invoice_config: $ref: '#/components/schemas/ApiPublicInvoiceConfig' team: type: string example: 'team_1234567890' description: 'Team ID this payment belongs to' idempotency_key: type: string example: 'unique_key_123' description: 'Idempotency key to prevent duplicate payments' from: type: string example: 'api' description: 'Source of payment creation' invoices: type: array items: type: string example: ['invoice_1234567890'] description: 'Associated invoice IDs' livemode: type: boolean example: true description: 'Whether this payment is in live mode' owner: type: string example: 'user_1234567890' description: 'User ID who owns this payment' payment_form: type: string example: '03' description: 'SAT payment form code' payments: type: array items: type: string example: [] description: 'Related payment IDs' receipts: type: array items: type: string example: ['receipt_1234567890'] description: 'Associated receipt IDs' refunds: type: array items: $ref: '#/components/schemas/ApiPublicRefund' description: 'Refunds associated with this payment' short_url: type: string example: 'https://pay.gigstack.io/p/abc123' description: 'Short URL for payment page' status: type: string enum: ['requires_payment_method', 'succeeded', 'canceled'] example: 'succeeded' description: 'Current payment status' total: type: number example: 1160.00 description: 'Total payment amount including taxes' total_refunded: type: number example: 0 description: 'Total amount refunded' subtotal: type: number example: 1000.00 description: 'Subtotal before taxes' taxes: type: number example: 160.00 description: 'Total tax amount' discount: type: number example: 0 description: 'Discount applied' withholding_taxes: type: number example: 0 description: 'Withholding taxes amount' created_at: type: number example: 1677651234 description: 'Unix timestamp of payment creation' succeeded_at: type: number nullable: true example: 1677651234 description: 'Unix timestamp when payment succeeded' payment_processor: type: string example: 'stripe' description: 'Payment processor used' payment_processor_details: $ref: '#/components/schemas/ApiPublicPaymentProcessorDetails' # Legacy alias for backward compatibility Payment: $ref: '#/components/schemas/ApiPublicPayment' PaymentInput: type: object required: - client - currency - items - paid properties: client: type: object properties: id: type: string nullable: true example: 'client_1234567890' search: type: object properties: on_key: type: string example: 'tax_id' on_value: type: string example: 'PEGJ800101ABC' auto_create: type: boolean example: true address: $ref: '#/components/schemas/ClientAddress' name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' company: type: string nullable: true example: 'Empresa SA de CV' phone: type: string nullable: true example: '+52 55 1234 5678' email: type: string format: email nullable: true example: 'juan.perez@ejemplo.com' bcc: type: array items: type: string format: email metadata: type: object additionalProperties: true legal_name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' tax_id: type: string nullable: true example: 'PEGJ800101ABC' use: type: string nullable: true example: 'P01' tax_system: type: string nullable: true example: '601' automation_type: type: string enum: ['pue_invoice', 'ppd_invoice_and_complement', 'none'] nullable: true example: 'pue_invoice' description: | Payment automation type: - `pue_invoice`: Create PUE (Pago en Una sola ExhibiciĂłn) invoice immediately when payment succeeds - `ppd_invoice_and_complement`: Create PPD (Pago en Parcialidades o Diferido) invoice immediately, then payment complement when payment succeeds - `none`: No automation, register payment only currency: type: string example: 'MXN' exchange_rate: type: number nullable: true example: 1.0 items: type: array items: type: object required: - quantity properties: id: type: string nullable: true example: 'service_1234567890' search: type: object properties: on_key: type: string example: 'sku' on_value: type: string example: 'CONS-001' auto_create: type: boolean example: true quantity: type: number example: 1 description: type: string nullable: true example: 'Consulting services' sku: type: string nullable: true example: 'CONS-001' product_key: type: string nullable: true example: '80141503' unit_key: type: string nullable: true example: 'E48' unit_name: type: string nullable: true example: 'Servicio' unit_price: type: number nullable: true example: 1000.00 taxes: type: array items: $ref: '#/components/schemas/TaxSchema' third_party: type: object properties: legal_name: type: string nullable: true example: 'Third Party SA' tax_id: type: string nullable: true example: 'TPR800101ABC' tax_system: type: string nullable: true example: '601' zip: type: string nullable: true example: '03100' paid: type: boolean example: true metadata: type: object nullable: true additionalProperties: true invoice_config: type: object nullable: true description: 'Invoice configuration with serie and folio' properties: serie: type: string nullable: true example: 'A' folio: type: number nullable: true example: 123 # Request Payment Input Schema (for /payments/request) RequestPaymentInput: type: object required: - client - currency - items - allowed_payment_methods properties: client: type: object properties: id: type: string nullable: true example: 'client_1234567890' search: type: object properties: on_key: type: string example: 'tax_id' on_value: type: string example: 'PEGJ800101ABC' auto_create: type: boolean example: true address: $ref: '#/components/schemas/ClientAddress' name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' company: type: string nullable: true example: 'Empresa SA de CV' phone: type: string nullable: true example: '+52 55 1234 5678' email: type: string format: email nullable: true example: 'juan.perez@ejemplo.com' bcc: type: array items: type: string format: email metadata: type: object additionalProperties: true legal_name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' tax_id: type: string nullable: true example: 'PEGJ800101ABC' use: type: string nullable: true example: 'P01' tax_system: type: string nullable: true example: '601' send_email: type: boolean nullable: true example: true description: 'Whether to send an email notification to the customer' emails: type: array nullable: true items: type: string format: email example: ['customer@example.com'] description: 'List of email addresses to send the payment request to' automation_type: type: string enum: ['pue_invoice', 'ppd_invoice_and_complement', 'none'] nullable: true example: 'pue_invoice' description: | Payment automation type: - `pue_invoice`: Create PUE (Pago en Una sola ExhibiciĂłn) invoice immediately when payment succeeds - `ppd_invoice_and_complement`: Create PPD (Pago en Parcialidades o Diferido) invoice immediately, then payment complement when payment succeeds - `none`: No automation, register payment only currency: type: string example: 'MXN' description: 'Currency code (ISO 4217)' exchange_rate: type: number nullable: true example: 1.0 description: 'Exchange rate for currency conversion. If not provided, the latest rate from our rates collection will be used automatically.' allowed_payment_methods: type: array items: type: string enum: ['card', 'bank', 'oxxo', 'stripe-spei'] example: ['card', 'bank', 'oxxo'] description: | Payment methods available to the customer: - `card`: Credit/debit card payments (requires Stripe integration) - `bank`: Mexican bank transfer (SPEI) - `oxxo`: OXXO convenience store payments (requires Stripe integration) - `stripe-spei`: Customer balance payments (requires Stripe integration) idempotency_key: type: string nullable: true example: 'payment-request-12345' description: 'Unique key to prevent duplicate payment requests' items: type: array items: type: object required: - quantity properties: id: type: string nullable: true example: 'service_1234567890' search: type: object properties: on_key: type: string example: 'sku' on_value: type: string example: 'CONS-001' auto_create: type: boolean example: true quantity: type: number example: 1 description: type: string nullable: true example: 'Consulting services' sku: type: string nullable: true example: 'CONS-001' product_key: type: string nullable: true example: '80141503' unit_key: type: string nullable: true example: 'E48' unit_name: type: string nullable: true example: 'Servicio' unit_price: type: number nullable: true example: 1000.00 taxes: type: array items: $ref: '#/components/schemas/TaxSchema' third_party: type: object properties: legal_name: type: string nullable: true example: 'Third Party SA' tax_id: type: string nullable: true example: 'TPR800101ABC' tax_system: type: string nullable: true example: '601' zip: type: string nullable: true example: '03100' metadata: type: object nullable: true additionalProperties: true description: 'Additional metadata to store with the payment' invoice_config: type: object nullable: true description: 'Optional invoice configuration to force specific folio and/or serie for the invoice. If folio is null or not provided, the automatic incrementing folio will be used.' properties: serie: type: string nullable: true example: 'A' description: 'Invoice serie. Will set/create the series for the team if provided.' folio: type: number nullable: true example: 123 description: 'Invoice folio number. If null or not provided, uses automatic incrementing folio. Note: when provided, duplicates may occur.' # Register Payment Input Schema (for /payments/register) RegisterPaymentInput: type: object required: - client - currency - items - payment_form properties: client: type: object properties: id: type: string nullable: true example: 'client_1234567890' search: type: object properties: on_key: type: string example: 'tax_id' on_value: type: string example: 'PEGJ800101ABC' auto_create: type: boolean example: true address: $ref: '#/components/schemas/ClientAddress' name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' company: type: string nullable: true example: 'Empresa SA de CV' phone: type: string nullable: true example: '+52 55 1234 5678' email: type: string format: email nullable: true example: 'juan.perez@ejemplo.com' bcc: type: array items: type: string format: email metadata: type: object additionalProperties: true legal_name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' tax_id: type: string nullable: true example: 'PEGJ800101ABC' use: type: string nullable: true example: 'P01' tax_system: type: string nullable: true example: '601' automation_type: type: string enum: ['pue_invoice', 'ppd_invoice_and_complement', 'none'] nullable: true example: 'pue_invoice' description: | Payment automation type: - `pue_invoice`: Create PUE (Pago en Una sola ExhibiciĂłn) invoice immediately when payment succeeds - `ppd_invoice_and_complement`: Create PPD (Pago en Parcialidades o Diferido) invoice immediately, then payment complement when payment succeeds - `none`: No automation, register payment only currency: type: string example: 'MXN' description: 'Currency code (ISO 4217)' exchange_rate: type: number nullable: true example: 1.0 description: 'Exchange rate for currency conversion. If not provided, the rate from the payment date (or current date if no date specified) will be fetched automatically from our rates collection.' items: type: array items: type: object required: - quantity properties: id: type: string nullable: true example: 'service_1234567890' search: type: object properties: on_key: type: string example: 'sku' on_value: type: string example: 'CONS-001' auto_create: type: boolean example: true quantity: type: number example: 1 description: type: string nullable: true example: 'Consulting services' sku: type: string nullable: true example: 'CONS-001' product_key: type: string nullable: true example: '80141503' unit_key: type: string nullable: true example: 'E48' unit_name: type: string nullable: true example: 'Servicio' unit_price: type: number nullable: true example: 1000.00 taxes: type: array items: $ref: '#/components/schemas/TaxSchema' third_party: type: object properties: legal_name: type: string nullable: true example: 'Third Party SA' tax_id: type: string nullable: true example: 'TPR800101ABC' tax_system: type: string nullable: true example: '601' zip: type: string nullable: true example: '03100' payment_form: type: string enum: [ '01', '02', '03', '04', '05', '06', '08', '12', '13', '14', '15', '17', '23', '24', '25', '26', '27', '28', '29', '30', '31', '99', ] example: '03' description: | Mexican SAT payment form code: - `01`: Cash - `02`: Check - `03`: Electronic transfer - `04`: Credit card - `05`: Electronic money - `06`: Digital money - `08`: Gift voucher - `12`: Credit for unregistered bills - `13`: Payment by subrogation - `14`: Payment by consignment - `15`: Condonation - `17`: Compensation - `23`: Novation - `24`: Confusion - `25`: Remission of debt - `26`: Prescription or expiration - `27`: To creditor's satisfaction - `28`: Credit card - `29`: Debit card - `30`: Service card - `31`: Applicable only to the complementary concept of donations - `99`: To be defined metadata: type: object nullable: true additionalProperties: true description: 'Additional metadata to store with the payment' idempotency_key: type: string nullable: true example: 'payment-register-12345' description: 'Unique key to prevent duplicate payment registrations. If a payment with this key already exists, the existing payment will be returned.' date: type: number nullable: true example: 1677651234000 description: 'Unix timestamp (in milliseconds) for when the payment was received. Must be in the past. Defaults to current time if not provided.' invoice_config: type: object nullable: true description: 'Optional invoice configuration to force specific folio and/or serie for the invoice. If folio is null or not provided, the automatic incrementing folio will be used.' properties: serie: type: string nullable: true example: 'A' description: 'Invoice serie. Will set/create the series for the team if provided.' folio: type: number nullable: true example: 123 description: 'Invoice folio number. If null or not provided, uses automatic incrementing folio. Note: when provided, duplicates may occur.' transfer_data: type: object nullable: true description: | Configuration for splitting payments between master and connect teams in a marketplace. Only available for master teams with marketplace-enabled billing accounts. properties: master: type: number minimum: 0 maximum: 100 example: 10 description: 'Percentage of the payment for the master team (0-100)' connect: type: string example: 'ABC123456789' description: 'Tax ID (RFC) or Team ID of the connect team. If not found, a new team will be created.' master_to: type: string enum: ['client', 'connect'] example: 'client' description: | Determines which client to assign to the master payment: - `client`: Use the original client from the request - `connect`: Create the connect team as a client for the master payment connect_to: type: string enum: ['client', 'master'] example: 'client' description: | Determines which client to assign to the connect payment: - `client`: Use the original client from the request - `master`: Create the master team as a client for the connect payment connect_custom_config: type: object nullable: true description: 'Optional configuration to customize items in the connect payment' properties: product_key: type: string example: '01010101' description: 'SAT product key to use for connect payment items' unit_key: type: string example: 'E48' description: 'SAT unit key to use for connect payment items' custom_description: type: string example: 'Professional consulting services' description: 'Custom description for connect payment items' custom_price: type: number example: 250.00 description: 'Fixed amount for connect payment (overrides percentage calculation). When set, connect gets this exact amount and master gets the remainder.' taxes: type: array description: 'Custom tax configuration for connect payment items (uses same schema as regular item taxes)' items: type: object required: - type - rate - withholding properties: type: type: string enum: ['IVA', 'ISR', 'IEPS'] example: 'IVA' description: 'Tax type' rate: type: number example: 0.16 description: 'Tax rate as decimal (0.16 = 16%)' withholding: type: boolean example: false description: 'true = retention (deducted from total), false = regular tax (added to subtotal)' base: type: number nullable: true description: 'Optional tax base amount' factor: type: string nullable: true example: 'Tasa' description: 'Optional tax factor' inclusive: type: boolean nullable: true description: 'Whether tax is included in the price' # Refund Payment Input Schema (for /payments/{id}/refund) RefundPaymentInput: type: object required: - reason - amount properties: reason: type: string example: 'Customer requested cancellation' description: 'Reason for the refund' amount: type: number example: 1160.00 description: 'Amount to refund' external_processor_refund: type: boolean nullable: true example: false description: 'Whether to process refund through external payment processor' # Mark Payment as Paid Input Schema (for /payments/{id}/paid) MarkPaymentAsPaidInput: type: object required: - payment_form properties: date: type: number nullable: true example: 1677651234 description: 'Unix timestamp when payment was received (optional, defaults to current time)' payment_form: $ref: '#/components/schemas/PaymentFormEnum' description: 'SAT payment form code' # Invoice Output Schema ApiPublicIncomeInvoice: type: object properties: uuid: type: string example: 'invoice_1234567890' description: 'Invoice UUID' client: $ref: '#/components/schemas/ApiPublicClient' created_at: type: number example: 1677651234 description: 'Invoice creation timestamp' currency: type: string example: 'MXN' description: 'Invoice currency' exchange_rate: type: number example: 1.0 description: 'Exchange rate used' total: type: number example: 1160.0 description: 'Total invoice amount' subtotal: type: number example: 1000.0 description: 'Subtotal before taxes' taxes: type: number example: 160.0 description: 'Total tax amount' discount: type: number example: 0.0 description: 'Total discount amount' withholding_taxes: type: number example: 0.0 description: 'Total withholding tax amount' series: type: string example: 'A' description: 'Invoice series' folio_number: type: number example: 123 description: 'Invoice folio number' invoice_type: type: string enum: ['I', 'E', 'P', 'N'] example: 'I' description: 'Invoice type (I=Income, E=Egress, P=Payment, N=Nomina)' use: type: string example: 'P01' description: 'Mexican SAT usage code' payment_form: type: string example: '03' description: 'Mexican SAT payment form code' payment_method: type: string example: 'PUE' description: 'Payment method (PUE/PPD)' status: type: string enum: ['draft', 'pending', 'stamped', 'cancelled'] example: 'stamped' description: 'Invoice status' livemode: type: boolean example: true description: 'Whether this is a live invoice' owner: type: string example: 'user_1234567890' description: 'User who created the invoice' from: type: string example: 'api' description: 'Source of invoice creation' items: type: array items: type: object properties: id: type: string example: 'item_1234567890' description: type: string example: 'Professional consulting services' product_key: type: string example: '80141503' quantity: type: number example: 1 unit_price: type: number example: 1000.0 unit_key: type: string example: 'E48' unit_name: type: string example: 'Servicio' sku: type: string example: 'CONS-001' taxability: type: string enum: ['01', '02'] example: '01' taxes: type: array items: $ref: '#/components/schemas/TaxSchema' payments: type: array items: type: string example: ['payment_1234567890'] description: 'Associated payment IDs' invoices: type: array items: type: string example: [] description: 'Related invoice IDs' stamp: type: object nullable: true properties: sello: type: string example: 'ABC123...' stamp_at: type: number example: 1677651234 cancellation: type: object nullable: true properties: cancellation_status: type: string example: 'cancelled' cancelled_at: type: number example: 1677651234 motive: type: string example: '02' code: type: string example: '201' verification_url: type: string example: 'https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx' description: 'SAT verification URL' exports: type: string example: '01' description: 'Export indicator' addenda: type: string example: '' description: 'Additional XML addenda' invoice_pdf_notes: type: string example: 'Additional notes for PDF' description: 'Custom notes for PDF generation' files: type: object nullable: true description: 'Base64 encoded files (only returned when return_files=true)' properties: pdf: type: string example: 'JVBERi0xLjQKJeLjz9MKMSAwIG9ia...' description: 'Base64 encoded PDF file' xml: type: string example: 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4...' description: 'Base64 encoded XML file' # Team Output Schema ApiPublicTeam: type: object properties: id: type: string example: 'team_1234567890' legal_name: type: string nullable: true example: 'Empresa de TecnologĂ­a S.A. de C.V.' description: 'Official registered legal name of the company/team' address: type: object nullable: true properties: country: type: string nullable: true example: 'MEX' street: type: string nullable: true example: 'Av. Insurgentes Sur 456' zip: type: string nullable: true example: '03100' city: type: string nullable: true example: 'Ciudad de MĂ©xico' state: type: string nullable: true example: 'CDMX' exterior: type: string nullable: true example: '96' interior: type: string nullable: true example: '10' neighborhood: type: string nullable: true example: 'Polanco' brand: type: object properties: alias: type: string nullable: true example: 'Mi Empresa' primary_color: type: string nullable: true example: '#007bff' secondary_color: type: string nullable: true example: '#6c757d' logo: type: string nullable: true example: 'https://example.com/logo.png' settings: type: object nullable: true properties: avoid_automations_on_currencies: type: array nullable: true items: type: string example: ['USD', 'EUR'] default_description: type: string nullable: true example: 'Default invoice description' taxes: type: array nullable: true items: type: object taxes_usd: oneOf: - type: array items: type: object - type: boolean nullable: true emails: type: object properties: invoices_bcc: type: array nullable: true items: type: string example: ['accounting@example.com'] avoid_invoice_emails: type: boolean nullable: true example: false avoid_test_invoice_emails: type: boolean nullable: true example: true avoid_receipts_emails: type: boolean nullable: true example: false override_item_description: type: string nullable: true example: 'Custom item description' global_invoice_disabled: type: boolean nullable: true example: false complements: type: array nullable: true items: type: object properties: data: type: string nullable: true description: type: string nullable: true type: type: string nullable: true uses_on_self_invoice_portal: type: array nullable: true items: type: string example: ['G03', 'S01'] invoice_pdf_notes: type: string nullable: true example: 'Additional notes for PDF' product_key: type: string nullable: true example: '81112209' unit_key: type: string nullable: true example: 'E48' use: type: string nullable: true example: 'G03' automate_complement_for_ppd_invoices: type: boolean nullable: true example: true withholding_taxes: type: array nullable: true items: type: object customer_portal_id: type: string nullable: true example: 'portal_1234567890' periodicity: type: object nullable: true properties: label: type: string example: 'Mes' value: type: string example: 'month' default_series: type: object properties: income: type: object properties: serie: type: string nullable: true example: 'A' complements: type: object properties: serie: type: string nullable: true example: 'P' credit_note: type: object properties: serie: type: string nullable: true example: 'NC' tax_id: type: string nullable: true example: 'EMP800101ABC' tax_system: type: string nullable: true example: '601' support_email: type: string nullable: true example: 'support@empresa.com' support_phone: type: string nullable: true example: '+52 55 1234 5678' owner: type: string nullable: true example: 'user_1234567890' created_at: type: number nullable: true example: 1677651234 sat: type: object properties: completed: type: boolean nullable: true example: true connected_at: type: number nullable: true example: 1677651234 csd_expires_at: type: number nullable: true example: 1924991999 members: type: array items: type: object properties: id: type: string nullable: true example: 'user_1234567890' email: type: string nullable: true example: 'member@empresa.com' role: type: string nullable: true example: 'admin' integrations: type: object properties: stripe: type: object properties: completed: type: boolean nullable: true example: false category: type: string nullable: true example: 'payments' mercadopago: type: object properties: completed: type: boolean nullable: true example: false category: type: string nullable: true example: 'payments' clip: type: object properties: completed: type: boolean nullable: true example: false category: type: string nullable: true example: 'payments' whmcs: type: object properties: completed: type: boolean nullable: true example: false category: type: string nullable: true example: 'payments' paypal: type: object properties: completed: type: boolean nullable: true example: false category: type: string nullable: true example: 'payments' openpay: type: object properties: completed: type: boolean nullable: true example: false category: type: string nullable: true example: 'payments' conekta: type: object properties: completed: type: boolean nullable: true example: false category: type: string nullable: true example: 'payments' bank: type: object properties: completed: type: boolean nullable: true example: false category: type: string nullable: true example: 'payments' shopify: type: object properties: completed: type: boolean nullable: true example: false category: type: string nullable: true example: 'payments' zapier: type: object properties: completed: type: boolean nullable: true example: false category: type: string nullable: true example: 'payments' airtable: type: object properties: completed: type: boolean nullable: true example: false category: type: string nullable: true example: 'payments' google_sheets: type: object properties: completed: type: boolean nullable: true example: false category: type: string nullable: true example: 'payments' hilos: type: object properties: completed: type: boolean nullable: true example: false category: type: string nullable: true example: 'messaging' credit_limit: type: number nullable: true example: 1000 description: 'Maximum number of documents (credits) the team can create per billing period. Null means no per-team limit (shared billing account pool).' used_credits: type: number example: 250 description: 'Number of credits used by this team in the current billing period.' credit_period_start: type: number nullable: true example: 1677651234000 description: 'Unix timestamp (milliseconds) when the current credit period started. Resets each billing cycle.' metadata: type: object nullable: true additionalProperties: true example: { 'custom_field': 'value' } # User Output Schema ApiPublicUser: type: object properties: id: type: string example: 'user_1234567890' email: type: string example: 'user@example.com' first_name: type: string nullable: true example: 'Juan' last_name: type: string nullable: true example: 'PĂ©rez' phone: type: string nullable: true example: '+52 55 1234 5678' teams: type: array items: type: string example: ['team_1234567890'] created_at: type: number example: 1677651234 company_role: type: string nullable: true example: 'CEO' address: type: object nullable: true properties: city: type: string nullable: true example: 'Ciudad de MĂ©xico' country: type: string nullable: true example: 'MEX' state: type: string nullable: true example: 'CDMX' # Webhook Schemas ApiPublicWebhook: type: object required: - id - url - events - status - owner - created_at properties: id: type: string example: 'wh_dyS2ZVTj' description: 'Unique webhook identifier' url: type: string format: url example: 'https://your-domain.com/webhooks/gigstack' description: 'HTTPS endpoint URL to receive webhook events' events: type: array items: type: string enum: - payment.created - payment.updated - payment.succeeded - payment.canceled - payment.deleted - payment.upcoming_due_date - invoice.created - invoice.canceled - invoice.failed - receipt.created - receipt.updated - receipt.completed - receipt.deleted - customer.created - customer.updated - customer.deleted - service.created - service.updated - service.deleted example: - payment.created - payment.succeeded - invoice.created description: 'Array of event types to subscribe to' status: type: string enum: [active, inactive] example: 'active' description: 'Webhook status - active or inactive' description: type: string nullable: true example: 'Production payment notifications' description: 'Optional description of the webhook purpose' owner: type: string example: '8UWdgXELUhf022vuoq249mtGytG2' description: 'User ID who created the webhook' created_at: type: number example: 1709090576567 description: 'Unix timestamp (milliseconds) of webhook creation' WebhookInput: type: object required: - url - events properties: url: type: string format: url example: 'https://your-domain.com/webhooks/gigstack' description: 'HTTPS endpoint URL to receive webhook events' events: type: array minItems: 1 items: type: string enum: - payment.created - payment.updated - payment.succeeded - payment.canceled - payment.deleted - payment.upcoming_due_date - invoice.created - invoice.canceled - invoice.failed - receipt.created - receipt.updated - receipt.completed - receipt.deleted - customer.created - customer.updated - customer.deleted - service.created - service.updated - service.deleted example: - payment.created - payment.succeeded description: 'Array of event types to subscribe to (at least one required)' description: type: string nullable: true example: 'Production webhook for payment events' description: 'Optional description of the webhook purpose' status: type: string enum: [active, inactive] default: active nullable: true example: 'active' description: 'Webhook status - defaults to active' WebhookUpdateInput: type: object properties: url: type: string format: url nullable: true example: 'https://new-domain.com/webhooks/gigstack' description: 'HTTPS endpoint URL to receive webhook events' events: type: array minItems: 1 nullable: true items: type: string enum: - payment.created - payment.updated - payment.succeeded - payment.canceled - payment.deleted - payment.upcoming_due_date - invoice.created - invoice.canceled - invoice.failed - receipt.created - receipt.updated - receipt.completed - receipt.deleted - customer.created - customer.updated - customer.deleted - service.created - service.updated - service.deleted example: - payment.created - payment.succeeded - invoice.created description: 'Array of event types to subscribe to' description: type: string nullable: true example: 'Updated webhook description' description: 'Optional description of the webhook purpose' status: type: string enum: [active, inactive] nullable: true example: 'inactive' description: 'Webhook status - active or inactive' # Team Schemas Team: type: object properties: id: type: string example: 'team_1234567890' name: type: string example: 'My Company' settings: type: object created_at: type: number example: 1677651234 TeamInput: type: object properties: address: type: object nullable: true properties: country: type: string example: 'MEX' street: type: string nullable: true example: 'Av. Insurgentes Sur' zip: type: string nullable: true example: '03100' city: type: string nullable: true example: 'Ciudad de MĂ©xico' state: type: string nullable: true example: 'CDMX' exterior: type: string nullable: true example: '123' interior: type: string nullable: true example: '4B' municipality: type: string nullable: true example: 'Benito JuĂĄrez' neighborhood: type: string nullable: true example: 'Del Valle' brand: type: object nullable: true properties: alias: type: string example: 'My Company' primary_color: type: string nullable: true example: '#FF0000' secondary_color: type: string nullable: true example: '#00FF00' logo: type: string nullable: true example: 'https://example.com/logo.png' metadata: type: object nullable: true additionalProperties: true description: 'Additional metadata to store with the team' support_email: type: string nullable: true format: email example: 'support@company.com' support_phone: type: string nullable: true example: '+52 55 1234 5678' tax_id: type: string nullable: true example: 'ABC123456789' tax_system: type: string nullable: true example: '601' generate_onboarding_url: type: boolean nullable: true example: true description: 'Generate onboarding URL for team setup' add_members: type: array nullable: true description: 'Array of members to add to the team on creation' items: type: object required: - id properties: id: type: string description: 'User ID to add as a team member' example: 'user123abc' role: type: string description: 'Role for the team member. Defaults to "viewer" if not specified.' enum: - admin - editor - viewer default: viewer example: 'editor' example: - id: 'user123abc' role: 'editor' - id: 'user456def' role: 'admin' legal_name: type: string nullable: true example: 'Empresa de TecnologĂ­a S.A. de C.V.' description: 'Legal name of the team/company' add_master_team_members: type: boolean nullable: true example: false description: 'When true, copies all members from the master team to the newly created team with their existing permissions' credit_limit: type: number nullable: true example: 1000 description: 'Maximum number of documents (credits) the team can create per billing period. When null or omitted, the team shares the billing account pool with no per-team cap.' TeamSettingsInput: type: object properties: keep_full_legal_name: type: boolean nullable: true example: false description: 'Keep full legal name in documents' default_description: type: string nullable: true example: 'Consulting services' description: 'Default description for items' taxes: type: array items: type: object nullable: true description: 'Default taxes configuration for MXN' taxes_usd: type: array items: type: object nullable: true description: 'Default taxes configuration for USD' emails: type: object nullable: true properties: invoices_bcc: type: array items: type: string format: email nullable: true example: ['admin@company.com'] description: 'BCC emails for invoices' avoid_invoice_emails: type: boolean nullable: true example: false description: 'Disable invoice emails' avoid_test_invoice_emails: type: boolean nullable: true example: true description: 'Disable test invoice emails' avoid_receipts_emails: type: boolean nullable: true example: false description: 'Disable receipt emails' override_item_description: type: string nullable: true example: 'Professional services' description: 'Override description for all items' global_invoice_disabled: type: boolean nullable: true example: false description: 'Disable global invoice functionality' complements: type: array items: type: object nullable: true description: 'CFDI complements configuration' uses_on_self_invoice_portal: type: array items: type: string nullable: true example: ['P01', 'P02'] description: 'Available CFDI uses on self-invoice portal' invoice_pdf_notes: type: string nullable: true example: 'Additional notes for PDF invoices' description: 'Default notes to include in invoice PDFs' product_key: type: string nullable: true example: '80141503' description: 'Default SAT product key' unit_key: type: string nullable: true example: 'E48' description: 'Default SAT unit key' use: type: string nullable: true example: 'P01' description: 'Default CFDI use' automate_complement_for_ppd_invoices: type: boolean nullable: true example: false description: 'Automatically create payment complement for PPD invoices' withholding_taxes: type: array items: type: object nullable: true description: 'Withholding taxes configuration' periodicity: type: string nullable: true enum: ['day', 'week', 'two_weeks', 'month', 'two_months'] example: 'month' description: 'Default billing/invoicing period for the team' default_series: type: object nullable: true properties: income: type: object nullable: true properties: serie: type: string nullable: true example: 'A' description: 'Default income series' folio_number_live: type: number nullable: true example: 1001 description: 'Next folio number for live environment' folio_number_test: type: number nullable: true example: 1 description: 'Next folio number for test environment' complements: type: object nullable: true properties: serie: type: string nullable: true example: 'C' description: 'Default complements series' folio_number_live: type: number nullable: true example: 1001 description: 'Next folio number for live environment' folio_number_test: type: number nullable: true example: 1 description: 'Next folio number for test environment' credit_note: type: object nullable: true properties: serie: type: string nullable: true example: 'N' description: 'Default credit note series' folio_number_live: type: number nullable: true example: 1001 description: 'Next folio number for live environment' folio_number_test: type: number nullable: true example: 1 description: 'Next folio number for test environment' # Team Settings Response Schema TeamSettings: type: object properties: keep_full_legal_name: type: boolean nullable: true example: false description: 'Keep full legal name in documents' default_description: type: string nullable: true example: 'Consulting services' description: 'Default description for items' taxes: type: array items: $ref: '#/components/schemas/TaxElement' nullable: true description: 'Default taxes configuration for MXN' taxes_usd: type: array items: $ref: '#/components/schemas/TaxElement' nullable: true description: 'Default taxes configuration for USD' emails: type: object nullable: true properties: invoices_bcc: type: array items: type: string format: email nullable: true example: ['admin@company.com'] description: 'BCC emails for invoices' avoid_invoice_emails: type: boolean nullable: true example: false description: 'Disable invoice emails' avoid_test_invoice_emails: type: boolean nullable: true example: true description: 'Disable test invoice emails' avoid_receipts_emails: type: boolean nullable: true example: false description: 'Disable receipt emails' override_item_description: type: string nullable: true example: 'Professional services' description: 'Override description for all items' global_invoice_disabled: type: boolean nullable: true example: false description: 'Disable global invoice functionality' complements: type: array items: type: object properties: type: type: string example: 'custom' data: type: string example: '...' nullable: true description: 'CFDI complements configuration' uses_on_self_invoice_portal: type: array items: type: string nullable: true example: ['P01', 'P02'] description: 'Available CFDI uses on self-invoice portal' invoice_pdf_notes: type: string nullable: true example: 'Additional notes for PDF invoices' description: 'Default notes to include in invoice PDFs' product_key: type: string nullable: true example: '80141503' description: 'Default SAT product key' unit_key: type: string nullable: true example: 'E48' description: 'Default SAT unit key' use: type: string nullable: true example: 'P01' description: 'Default CFDI use' automate_complement_for_ppd_invoices: type: boolean nullable: true example: false description: 'Automatically create payment complement for PPD invoices' withholding_taxes: type: array items: $ref: '#/components/schemas/TaxElement' nullable: true description: 'Withholding taxes configuration' periodicity: type: string nullable: true enum: ['day', 'week', 'two_weeks', 'month', 'two_months'] example: 'month' description: 'Default billing/invoicing period for the team' default_series: type: object nullable: true properties: income: type: object nullable: true properties: serie: type: string nullable: true example: 'A' description: 'Default income series' folio_number_live: type: number nullable: true example: 1001 description: 'Next folio number for live environment' folio_number_test: type: number nullable: true example: 1 description: 'Next folio number for test environment' complements: type: object nullable: true properties: serie: type: string nullable: true example: 'C' description: 'Default complements series' folio_number_live: type: number nullable: true example: 1001 description: 'Next folio number for live environment' folio_number_test: type: number nullable: true example: 1 description: 'Next folio number for test environment' credit_note: type: object nullable: true properties: serie: type: string nullable: true example: 'N' description: 'Default credit note series' folio_number_live: type: number nullable: true example: 1001 description: 'Next folio number for live environment' folio_number_test: type: number nullable: true example: 1 description: 'Next folio number for test environment' created_at: type: number example: 1677651234 description: 'Unix timestamp when settings were created' updated_at: type: number example: 1677651234 description: 'Unix timestamp when settings were last updated' # User Schemas User: type: object properties: id: type: string example: 'user_1234567890' email: type: string format: email example: 'user@example.com' name: type: string example: 'John Doe' role: type: string example: 'admin' created_at: type: number example: 1677651234 UserInput: type: object properties: email: type: string format: email nullable: true example: 'user@example.com' first_name: type: string nullable: true example: 'John' last_name: type: string nullable: true example: 'Doe' phone: type: string nullable: true example: '+52 55 1234 5678' company_role: type: string nullable: true example: 'Manager' address: type: object nullable: true description: 'User address information. Note: municipality field is accepted in requests but not returned in responses.' properties: country: type: string nullable: true example: 'MEX' street: type: string nullable: true example: 'Av. Insurgentes Sur' zip: type: string nullable: true example: '03100' city: type: string nullable: true example: 'Ciudad de MĂ©xico' state: type: string nullable: true example: 'CDMX' exterior: type: string nullable: true example: '123' municipality: type: string nullable: true description: 'Municipality name (accepted in requests, stored in database, but not returned in responses)' example: 'Benito JuĂĄrez' neighborhood: type: string nullable: true example: 'Del Valle' auto_join: type: boolean nullable: true description: 'If true, automatically adds the user to the team associated with the API key. Defaults to false if not specified. When true and role is specified, the user will be added with that role.' example: true role: type: string nullable: true enum: ['editor', 'admin', 'viewer'] description: 'Role to assign to the user when auto_join is true. Can be "editor", "admin", or "viewer". Defaults to "viewer" if not specified. This parameter works in conjunction with auto_join - when auto_join is true, the user will be added to the team with the specified role.' example: 'viewer' # Series Schemas - For invoice series and folio management SeriesInput: type: object required: - name - type properties: name: type: string example: 'A' description: 'Series name/identifier (typically one or two letters)' type: type: string enum: ['income', 'complements', 'credit_note'] example: 'income' description: | Series type: - `income`: For income invoices - `complements`: For payment complements - `credit_note`: For credit notes/refunds folio_number_live: type: number nullable: true example: 1001 description: 'Starting folio number for live environment' folio_number_test: type: number nullable: true example: 1 description: 'Starting folio number for test environment' is_default: type: boolean nullable: true example: true description: 'Whether this is the default series for its type' enabled: type: boolean nullable: true example: true description: 'Whether this series is active' metadata: type: object nullable: true additionalProperties: true description: 'Additional metadata for the series' Series: type: object properties: id: type: string example: 'series_1234567890' description: 'Unique series identifier' name: type: string example: 'A' description: 'Series name/identifier' type: type: string enum: ['income', 'complements', 'credit_note'] example: 'income' description: 'Series type' folio_number_live: type: number example: 1001 description: 'Current folio number for live environment' folio_number_test: type: number example: 1 description: 'Current folio number for test environment' is_default: type: boolean example: true description: 'Whether this is the default series for its type' enabled: type: boolean example: true description: 'Whether this series is active' team: type: string example: 'team_1234567890' description: 'Team ID that owns this series' owner: type: string example: 'user_1234567890' description: 'User ID who created this series' livemode: type: boolean example: true description: 'Whether this series is in live mode' created_at: type: number example: 1677651234 description: 'Unix timestamp when series was created' updated_at: type: number example: 1677651234 description: 'Unix timestamp when series was last updated' metadata: type: object nullable: true additionalProperties: true description: 'Additional metadata for the series' # Receipt Schema - For receipt input ReceiptInput: type: object required: - client - currency - items properties: client: type: object properties: id: type: string nullable: true example: 'client_1234567890' description: 'Existing client ID' search: type: object properties: on_key: type: string example: 'tax_id' description: 'Field to search client on' on_value: type: string example: 'PEGJ800101ABC' description: 'Value to search for' auto_create: type: boolean example: true description: 'Create client if not found' safety_check: type: boolean example: false description: 'When true, prevents using multiple matching results (returns error). When false, uses the first result found. Default: false' address: $ref: '#/components/schemas/ClientAddress' name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' company: type: string nullable: true example: 'Empresa SA de CV' phone: type: string nullable: true example: '+52 55 1234 5678' email: type: string format: email nullable: true example: 'juan.perez@ejemplo.com' legal_name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' tax_id: type: string nullable: true example: 'PEGJ800101ABC' metadata: type: object additionalProperties: true currency: type: string example: 'MXN' description: 'Currency code (ISO 4217)' exchange_rate: type: number nullable: true example: 1.0 description: 'Exchange rate to use for currency conversion' items: type: array items: $ref: '#/components/schemas/ItemSchema' description: 'Receipt items' metadata: type: object nullable: true additionalProperties: true description: 'Additional metadata - accepts any custom properties for tracking business data, references, or integration identifiers. All properties are preserved and returned as-is.' periodicity: type: string nullable: true enum: ['day', 'week', 'two_weeks', 'month', 'two_months'] example: 'month' description: 'Receipt validity period' invoice_config: type: object nullable: true properties: folio: type: number nullable: true example: 123 description: 'Invoice folio number' serie: type: string nullable: true example: 'A' description: 'Invoice series' description: 'Invoice configuration for future stamping' payment_form: type: string nullable: true example: '01' description: 'SAT payment form code' idempotency_key: type: string nullable: true example: 'receipt-key-12345' description: 'Unique key to prevent duplicate receipts. If a receipt with this key already exists, the existing receipt will be returned.' # Shared/Global Schemas ApiPublicSearch: type: object required: - on_key - on_value - auto_create properties: on_key: type: string example: 'tax_id' description: 'Field to search on' on_value: type: string example: 'PEGJ800101ABC' description: 'Value to search for' auto_create: type: boolean example: true description: 'Whether to create the resource if not found' safety_check: type: boolean example: false description: 'When true, prevents using multiple matching results (returns error). When false, uses the first result found. Default: false' ApiPublicThirdParty: type: object required: - legal_name - tax_id - tax_system - zip properties: legal_name: type: string example: 'Third Party SA de CV' description: 'Legal name of the third party' tax_id: type: string example: 'TPR800101ABC' description: 'RFC (Tax ID) of the third party' tax_system: type: string example: '601' description: 'SAT tax system code' zip: type: string example: '03100' description: 'Postal code of the third party' ApiPublicInvoiceConfig: type: object properties: serie: type: string nullable: true example: 'A' description: 'Invoice series' folio: type: string nullable: true example: '123' description: 'Invoice folio number' ApiPublicRefund: type: object required: - id - reason - created_at - total properties: id: type: string example: 'refund_1234567890' description: 'Unique refund identifier' items: type: array items: $ref: '#/components/schemas/ApiPublicService' nullable: true description: 'Items being refunded' reason: type: string example: 'Customer requested cancellation' description: 'Reason for the refund' created_at: type: number example: 1677651234 description: 'Unix timestamp of when the refund was created' total: type: number example: 1160.00 description: 'Total refund amount' ApiPublicAutomations: type: object properties: triggered_by: type: string enum: ['successful_payment', 'payment_created', 'invoice_created'] nullable: true example: 'successful_payment' description: 'Event that triggers the automation' creates: type: string enum: ['invoice', 'payment', 'ppd_invoice', 'payment_complement'] example: 'invoice' description: 'What the automation creates' description: type: string example: 'Create PUE invoice on successful payment' description: 'Human-readable description of the automation' TaxElement: type: object required: - type - rate properties: base: oneOf: - type: number - type: string nullable: true example: 100 description: 'Taxable base amount. Accepts number or numeric string. If null, calculated automatically from item price.' factor: type: string nullable: true example: 'Tasa' description: 'SAT tax factor (Tasa, Cuota, Exento)' inclusive: type: boolean nullable: true example: false description: 'Whether the tax is included in the unit price' rate: type: number example: 0.16 description: 'Tax rate (e.g., 0.16 for 16% IVA)' type: type: string enum: ['IVA', 'ISR', 'IEPS'] example: 'IVA' description: 'Type of tax' withholding: type: boolean nullable: true example: false description: 'Whether this is a withholding tax' ClientAddress: type: object nullable: true properties: country: type: string nullable: true example: 'MEX' street: type: string nullable: true example: 'Av. Insurgentes Sur' zip: type: string nullable: true example: '03100' city: type: string nullable: true example: 'Ciudad de MĂ©xico' state: type: string nullable: true example: 'CDMX' exterior: type: string nullable: true example: '123' interior: type: string nullable: true example: '4B' municipality: type: string nullable: true example: 'Benito JuĂĄrez' neighborhood: type: string nullable: true example: 'Del Valle' TaxSchema: type: object properties: base: oneOf: - type: number - type: string nullable: true description: 'Taxable base amount. Accepts number or numeric string. If null, calculated automatically from item price.' example: 100 factor: type: string nullable: true example: 'Tasa' inclusive: type: boolean nullable: true example: false rate: type: number nullable: true example: 0.16 type: type: string enum: ['IVA', 'ISR', 'IEPS'] nullable: true example: 'IVA' withholding: type: boolean nullable: true example: false # Response Schemas StandardSuccessResponse: type: object required: - message - data properties: message: type: string example: 'Operation completed successfully' data: type: object ListResponse: type: object required: - message - data - has_more - total_results properties: message: type: string example: 'Items retrieved successfully' data: type: array items: type: object next: type: string nullable: true description: Cursor for next page example: 'eyJjcmVhdGVkX2F0IjoxNjc3NjUxMjM0fQ==' has_more: type: boolean example: true total_results: type: number example: 150 ErrorResponse: type: object required: - message - error properties: message: type: string example: 'An error occurred' error: type: string example: 'Specific error description' ValidationErrorResponse: type: object required: - message - error properties: message: type: string example: 'Invalid request body' error: type: string example: 'Validation failed' UnauthorizedError: type: object required: - message - error properties: message: type: string example: 'Unauthorized' error: type: string example: 'Invalid or missing authorization token' NotFoundError: type: object required: - message - error properties: message: type: string example: 'Resource not found' error: type: string example: 'The requested resource could not be found' InternalServerError: type: object required: - message - error properties: message: type: string example: 'Internal server error' error: type: string example: 'An unexpected error occurred' # ============================================================================= # ENUM SCHEMAS - Payment, Automation, and SAT-related enums # ============================================================================= PaymentMethodEnum: type: string enum: ['card', 'spei', 'oxxo', 'stripe-spei'] description: | Payment method options: - `card`: Credit/debit card payments *(requires Stripe integration)* - `spei`: Mexican bank transfer (SPEI) - `oxxo`: OXXO convenience store payments *(requires Stripe integration)* - `stripe-spei`: Customer balance payments *(requires Stripe integration)* **Note:** `card`, `oxxo`, and `stripe-spei` are only available when your team has Stripe connected. example: 'card' PaymentFormEnum: type: string enum: - '01' # Efectivo - '02' # Cheque nominativo - '03' # Transferencia electrĂłnica de fondos - '04' # Tarjeta de crĂ©dito - '05' # Monedero electrĂłnico - '06' # Dinero electrĂłnico - '08' # Vales de despensa - '12' # DaciĂłn en pago - '13' # Pago por subrogaciĂłn - '14' # Pago por consignaciĂłn - '15' # CondonaciĂłn - '17' # CompensaciĂłn - '23' # NovaciĂłn - '24' # ConfusiĂłn - '25' # RemisiĂłn de deuda - '26' # PrescripciĂłn o caducidad - '27' # A satisfacciĂłn del acreedor - '28' # Tarjeta de dĂ©bito - '29' # Tarjeta de servicios - '30' # AplicaciĂłn de anticipos - '31' # Intermediario pagos - '99' # Por definir description: | SAT payment form codes (c_FormaPago) according to Mexican tax regulations. Most common forms: - `01`: Cash (Efectivo) - `03`: Electronic funds transfer (Transferencia electrĂłnica) - `04`: Credit card (Tarjeta de crĂ©dito) - `28`: Debit card (Tarjeta de dĂ©bito) example: '03' AutomationTypeEnum: type: string enum: ['pue_invoice', 'ppd_invoice_and_complement', 'none'] description: | Payment automation types for invoice generation: - `payment`: Create PUE (Pago en Una sola ExhibiciĂłn) invoice immediately - `payment_and_complement`: Create PPD invoice and payment complement - `none`: No automation, register payment only example: 'pue_invoice' # ============================================================================= # ENHANCED ITEM SCHEMA - Items with third-party and SAT compliance support # ============================================================================= ItemSchema: type: object required: - quantity properties: id: type: string nullable: true example: 'service_1234567890' description: 'Service/product ID reference' search: type: object properties: on_key: type: string example: 'sku' description: 'Field to search on (sku, name, etc.)' on_value: type: string example: 'CONS-001' description: 'Value to search for' auto_create: type: boolean example: true description: 'Create service if not found' safety_check: type: boolean example: false description: 'When true, prevents using multiple matching results (returns error). When false, uses the first result found. Default: false' quantity: type: number example: 1 description: 'Item quantity' description: type: string nullable: true example: 'Consulting services' description: 'Item description' sku: type: string nullable: true example: 'CONS-001' description: 'Stock keeping unit' product_key: type: string nullable: true example: '80141503' description: 'SAT product key (c_ClaveProdServ)' unit_key: type: string nullable: true example: 'E48' description: 'SAT unit key (c_ClaveUnidad)' unit_name: type: string nullable: true example: 'Servicio' description: 'Unit name' unit_price: type: number nullable: true example: 1000.00 description: 'Unit price' discount: type: number nullable: true example: 0 description: 'Discount amount or percentage' taxes: type: array items: $ref: '#/components/schemas/TaxElement' description: 'Tax elements applied to this item' third_party: type: object nullable: true properties: legal_name: type: string example: 'Third Party SA' description: 'Third party legal name' tax_id: type: string example: 'TPR800101ABC' description: 'Third party RFC (tax ID)' tax_system: type: string example: '601' description: 'Third party tax system' zip: type: string example: '03100' description: 'Third party ZIP code' description: 'Third party information for items provided by external parties' metadata: type: object nullable: true additionalProperties: true description: 'Additional metadata for the item' # SAT Support Documents - For 2026 Mexican fiscal reform compliance SATDocument: type: object required: - id - document_type - name - file_url - file_name - file_size - mime_type - compliance_status - created_at - linked_entities properties: id: type: string example: 'doc_abc123xyz' description: 'Unique document identifier' document_type: type: string enum: - contract - delivery_proof - payment_proof - communication - payment_confirmation - subscription_info - cronograma description: 'Type of supporting document' name: type: string example: 'Service Contract.pdf' description: 'Document name' description: type: string nullable: true example: 'Main service contract for consulting services' description: 'Optional document description' file_url: type: string format: uri example: 'https://storage.googleapis.com/...' description: 'Public URL to access the document' file_name: type: string example: 'contract.pdf' description: 'Original filename' file_size: type: integer example: 245680 description: 'File size in bytes' mime_type: type: string example: 'application/pdf' description: 'MIME type of the file' compliance_status: type: string enum: - pending_review - valid - requires_update - expired - rejected description: 'SAT compliance status' compliance_notes: type: string nullable: true description: 'Notes about compliance status' valid_from: type: integer format: int64 nullable: true description: 'Validity start timestamp (milliseconds)' valid_until: type: integer format: int64 nullable: true description: 'Validity end timestamp (milliseconds)' ai_extraction: type: object nullable: true properties: extracted_at: type: integer format: int64 description: 'Extraction timestamp (milliseconds)' extracted_by: type: string example: 'ai' description: 'Source of extraction' model: type: string example: 'gemini-3-flash' description: 'AI model used' confidence: type: number format: float example: 0.95 description: 'Confidence score (0-1)' extracted_data: type: object additionalProperties: true description: 'Extracted structured data' warnings: type: array items: type: string description: 'Extraction warnings' description: 'AI extraction results if analyzed' audits: type: array items: type: object properties: context_type: type: string enum: [invoice, payment, receipt] description: 'Type of entity audited against' context_id: type: string description: 'ID of entity audited against' audited_at: type: integer format: int64 description: 'Audit timestamp (milliseconds)' result: type: string enum: [valid, warning, mismatch] description: 'Audit result' summary: type: string description: 'Audit summary' details: type: object additionalProperties: true description: 'Detailed audit results' description: 'Context-specific audit results' created_at: type: integer format: int64 example: 1677651234000 description: 'Creation timestamp (milliseconds)' created_by: type: string example: 'user_abc123' description: 'User who created the document' updated_at: type: integer format: int64 example: 1677651234000 description: 'Last update timestamp (milliseconds)' linked_entities: type: array items: type: object properties: entity_type: type: string enum: [invoice, payment, receipt, client] description: 'Type of linked entity' entity_id: type: string description: 'ID of linked entity' linked_at: type: integer format: int64 description: 'Link timestamp (milliseconds)' description: 'Entities this document is linked to' UploadSupportDocumentInput: type: object required: - file - documentType properties: file: type: string format: binary description: 'The file to upload (PDF or image, max 10MB)' documentType: type: string enum: - contract - delivery_proof - payment_proof - communication - payment_confirmation - subscription_info description: 'Type of supporting document' name: type: string example: 'Service Contract' description: 'Optional custom name for the document' description: type: string example: 'Master services agreement for 2026' description: 'Optional description of the document' paths: # ============================================================================= # CLIENTS - Organized by HTTP Method (GET → POST → PUT → DELETE) # ============================================================================= /clients: get: tags: - Clients summary: List clients description: | Retrieve a paginated list of clients with powerful filtering capabilities. **gigstack Connect:** Access other teams' clients using the `team` parameter. **Filtering Options:** - Filter by creation date using comparison operators - Filter by metadata fields using dot or underscore notation (e.g., `metadata.external_id` or `metadata_external_id`) security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - $ref: '#/components/parameters/LimitParam' - $ref: '#/components/parameters/NextParam' - $ref: '#/components/parameters/OrderByParam' - $ref: '#/components/parameters/SortParam' - $ref: '#/components/parameters/CreatedGteParam' - $ref: '#/components/parameters/CreatedLteParam' - name: metadata.{key} in: query description: | Filter by any metadata field using dot notation (e.g., `metadata.external_id=EXT-123`) or underscore notation (e.g., `metadata_external_id=EXT-123`). Both formats are supported and equivalent. Uses Typesense search for efficient querying without requiring Firestore indexes. required: false schema: type: string style: form - name: page in: query description: | Page number for pagination when using metadata filters (default 1). Only applies when filtering by metadata fields. required: false schema: type: integer minimum: 1 default: 1 responses: '200': description: Clients retrieved successfully content: application/json: schema: type: object properties: message: type: string example: 'Clients retrieved successfully' data: type: array items: $ref: '#/components/schemas/ApiPublicClient' has_more: type: boolean example: false total_results: type: integer example: 25 next: type: string nullable: true example: 'eyJjcmVhdGVkX2F0IjoxNjc3NjUxMjM0fQ==' example: message: 'Clients retrieved successfully' data: - id: 'client_1234567890' name: 'Juan PĂ©rez GarcĂ­a' email: 'juan.perez@ejemplo.com' tax_id: 'PEGJ800101ABC' tax_system: '601' legal_name: 'Juan PĂ©rez GarcĂ­a' address: street: 'Av. Insurgentes Sur 123' zip: '03100' city: 'Ciudad de MĂ©xico' state: 'CDMX' country: 'MEX' is_valid: true livemode: true created_at: 1677651234 team: 'team_1234567890' owner: 'user_1234567890' has_more: false total_results: 1 '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' post: tags: - Clients summary: Create client description: | Create a new client with fiscal information for Mexican tax compliance. **Duplicate Prevention (Upsert):** Use the `search` parameter to find existing clients before creating: - If a match is found and `search.update` is `false` (default): Returns the existing client without modifications. - If a match is found and `search.update` is `true`: Updates the existing client with the provided data and returns it. - If no match is found: Creates a new client. This is useful for integrations that may send the same client multiple times. **gigstack Connect:** Create clients for other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ClientInput' example: name: 'Juan PĂ©rez GarcĂ­a' email: 'juan.perez@ejemplo.com' company: 'Empresa SA de CV' phone: '+52 55 1234 5678' legal_name: 'Juan PĂ©rez GarcĂ­a' tax_id: 'PEGJ800101ABC' use: 'P01' tax_system: '601' address: country: 'MEX' street: 'Av. Insurgentes Sur' zip: '03100' city: 'Ciudad de MĂ©xico' state: 'CDMX' exterior: '123' interior: '4B' municipality: 'Benito JuĂĄrez' neighborhood: 'Del Valle' bcc: ['admin@empresa.com'] metadata: custom_field: 'value' department: 'sales' defaults: keep_full_legal_name: false issue_automatic_invoices: false issue_invoiceable_receipts: true search: on_key: 'tax_id' on_value: 'PEGJ800101ABC' update: false responses: '200': description: Existing client found (when using `search` parameter) content: application/json: schema: type: object properties: message: type: string example: 'Existing client found' data: $ref: '#/components/schemas/ApiPublicClient' examples: existingClient: summary: Existing client found value: message: 'Existing client found' data: id: 'client_1234567890' name: 'Juan PĂ©rez GarcĂ­a' email: 'juan.perez@ejemplo.com' tax_id: 'PEGJ800101ABC' tax_system: '601' legal_name: 'Juan PĂ©rez GarcĂ­a' address: street: 'Av. Insurgentes Sur 123' zip: '03100' city: 'Ciudad de MĂ©xico' state: 'CDMX' country: 'MEX' is_valid: true livemode: true created_at: 1677651234 team: 'team_1234567890' owner: 'user_1234567890' from: 'api' existingClientUpdated: summary: Existing client found and updated value: message: 'Existing client found and updated' data: id: 'client_1234567890' name: 'Juan PĂ©rez GarcĂ­a' email: 'juan.perez@ejemplo.com' tax_id: 'PEGJ800101ABC' tax_system: '601' legal_name: 'Juan PĂ©rez GarcĂ­a' address: street: 'Av. Insurgentes Sur 123' zip: '03100' city: 'Ciudad de MĂ©xico' state: 'CDMX' country: 'MEX' is_valid: true livemode: true created_at: 1677651234 team: 'team_1234567890' owner: 'user_1234567890' from: 'api' '201': description: Client created successfully content: application/json: schema: type: object properties: message: type: string example: 'Client created successfully' data: $ref: '#/components/schemas/ApiPublicClient' example: message: 'Client created successfully' data: id: 'client_1234567890' name: 'Juan PĂ©rez GarcĂ­a' email: 'juan.perez@ejemplo.com' tax_id: 'PEGJ800101ABC' tax_system: '601' legal_name: 'Juan PĂ©rez GarcĂ­a' address: street: 'Av. Insurgentes Sur 123' zip: '03100' city: 'Ciudad de MĂ©xico' state: 'CDMX' country: 'MEX' is_valid: true livemode: true created_at: 1677651234 team: 'team_1234567890' owner: 'user_1234567890' from: 'api' '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ValidationErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '409': description: Conflict - Multiple clients match the search criteria content: application/json: schema: type: object properties: success: type: boolean example: false error: type: object properties: code: type: string example: 'resource_conflict' message: type: string example: 'Multiple clients found matching tax_id="PEGJ800101ABC". Please use a more specific search criteria.' details: type: array items: type: string description: List of matching client IDs example: ['client_1234567890', 'client_0987654321'] '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' /clients/{id}: get: tags: - Clients summary: Get client description: | Retrieve a specific client by ID. **gigstack Connect:** Access other teams' clients using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string responses: '200': description: Client retrieved successfully content: application/json: schema: type: object properties: message: type: string example: 'Client retrieved successfully' data: $ref: '#/components/schemas/ApiPublicClient' example: message: 'Client retrieved successfully' data: id: 'client_1234567890' name: 'Juan PĂ©rez GarcĂ­a' email: 'juan.perez@ejemplo.com' tax_id: 'PEGJ800101ABC' tax_system: '601' legal_name: 'Juan PĂ©rez GarcĂ­a' address: street: 'Av. Insurgentes Sur 123' zip: '03100' city: 'Ciudad de MĂ©xico' state: 'CDMX' country: 'MEX' is_valid: true livemode: true created_at: 1677651234 team: 'team_1234567890' owner: 'user_1234567890' put: tags: - Clients summary: Update client description: | Update an existing client. **gigstack Connect:** Update other teams' clients using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ClientInput' example: name: 'Juan PĂ©rez GarcĂ­a' email: 'juan.perez.updated@ejemplo.com' company: 'Empresa SA de CV - Sucursal Norte' phone: '+52 55 1234 5678' legal_name: 'Juan PĂ©rez GarcĂ­a' tax_id: 'PEGJ800101ABC' use: 'P01' tax_system: '601' address: country: 'MEX' street: 'Av. Insurgentes Sur' zip: '03100' city: 'Ciudad de MĂ©xico' state: 'CDMX' exterior: '123' interior: '4B' municipality: 'Benito JuĂĄrez' neighborhood: 'Del Valle' bcc: ['admin@empresa.com', 'contabilidad@empresa.com'] metadata: updated_reason: 'Address change' priority_client: true defaults: keep_full_legal_name: true issue_automatic_invoices: true issue_invoiceable_receipts: true responses: '200': description: Client updated successfully content: application/json: schema: type: object properties: message: type: string example: 'Client updated successfully' data: $ref: '#/components/schemas/ApiPublicClient' example: message: 'Client updated successfully' data: id: 'client_1234567890' name: 'Juan PĂ©rez GarcĂ­a' email: 'juan.perez@ejemplo.com' tax_id: 'PEGJ800101ABC' tax_system: '601' legal_name: 'Juan PĂ©rez GarcĂ­a' address: street: 'Av. Insurgentes Sur 123' zip: '03100' city: 'Ciudad de MĂ©xico' state: 'CDMX' country: 'MEX' is_valid: true livemode: true created_at: 1677651234 team: 'team_1234567890' owner: 'user_1234567890' delete: tags: - Clients summary: Delete client description: | Delete a specific client. **gigstack Connect:** Delete other teams' clients using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string responses: '200': description: Client deleted successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /clients/search: get: tags: - Clients summary: Search clients description: | Full-text search across clients using Typesense. Provides fast, typo-tolerant search capabilities. **gigstack Connect:** Access other teams' clients using the `team` parameter. **Search Capabilities:** - Search across client name, email, tax ID, legal name, and metadata - Typo-tolerant fuzzy matching - Paginated results **Requirements:** - Typesense must be configured for your team - The `q` (or `query`) parameter is required security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - $ref: '#/components/parameters/SearchQueryParam' - $ref: '#/components/parameters/SearchQueryBackwardCompatParam' - $ref: '#/components/parameters/LimitParam' - $ref: '#/components/parameters/SearchPageParam' - $ref: '#/components/parameters/FieldsParam' responses: '200': description: Clients searched successfully content: application/json: schema: type: object required: - message - data - found - page - per_page - success - timestamp properties: message: type: string example: 'Clients searched successfully' data: type: array items: $ref: '#/components/schemas/ApiPublicClient' found: type: integer description: Total number of results found example: 15 page: type: integer description: Current page number example: 1 per_page: type: integer description: Number of results per page example: 10 success: type: boolean example: true timestamp: type: number format: int64 description: Unix timestamp in milliseconds example: 1677651234000 '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ValidationErrorResponse' examples: missing_query: summary: Missing query parameter value: message: 'Query parameter is required' error: 'missing_query' missing_typesense_key: summary: Typesense not configured value: message: 'Typesense API key not configured for this team' error: 'missing_typesense_key' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' /clients/validate/{id}: post: tags: - Clients summary: Validate client fiscal information description: | Validate client's fiscal information against SAT. **gigstack Connect:** Validate other teams' clients using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string responses: '200': description: Client validated successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /clients/customerportal: post: tags: - Clients summary: Get client customer portal access token description: | Generate a secure access token for client customer portal. **gigstack Connect:** Access other teams' customer portal using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' requestBody: required: true content: application/json: schema: type: object properties: id: type: string format: string description: Client ID to generate access token for. example: 'client_1234567890' email: type: string format: email description: Client email address example: 'client@example.com' responses: '200': description: Customer portal access token generated successfully content: application/json: schema: type: object properties: message: type: string example: 'Customer portal retrieved successfully' data: type: object properties: url: type: string format: uri description: Complete portal URL with session parameters example: 'https://portal.gigstack.pro/portal_123?sessionId=otpcustomerportal_abc&c=secure_code_xyz' expires_at: type: number description: Token expiration timestamp (5 days from creation) example: 1693900800000 session_id: type: string description: Session identifier for the portal access example: 'otpcustomerportal_abc123' '400': description: Bad request - Missing email or team portal not configured content: application/json: schema: type: object properties: message: type: string example: 'Error getting customer portal' error: type: string example: 'Client ID or email is required' '500': description: Internal server error content: application/json: schema: type: object properties: error: type: string example: 'Failed to get client customer portal' /clients/csf: post: tags: - Clients summary: Upload CSF PDF to create or update client description: | Upload a CSF (Constancia de SituaciĂłn Fiscal) PDF file from SAT to automatically extract fiscal information and create a new client or update an existing one. **How it works:** 1. Upload the CSF PDF file as `multipart/form-data` 2. The system extracts RFC and CIF from the PDF 3. Validates the fiscal information against SAT 4. Creates a new client or updates an existing one with the fiscal data **Query Parameters:** - `client_id` (optional): If provided, updates the existing client. If omitted, creates a new client. **Extracted Information:** - Legal name (RazĂłn Social) - RFC (Tax ID) - Fiscal regime (RĂ©gimen Fiscal) - Fiscal type (company/individual) - Fiscal status - Complete address (street, exterior/interior number, neighborhood, city, state, zip code) **gigstack Connect:** Create or update clients for other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: client_id in: query required: false schema: type: string description: Optional client ID to update. If not provided, creates a new client. example: 'client_1234567890' requestBody: required: true content: multipart/form-data: schema: type: object required: - file properties: file: type: string format: binary description: CSF PDF file from SAT responses: '200': description: Client updated successfully with CSF data content: application/json: schema: type: object properties: message: type: string example: 'Client updated with CSF data' data: $ref: '#/components/schemas/ApiPublicClient' example: message: 'Client updated with CSF data' data: id: 'client_1234567890' name: 'Empresa Ejemplo SA de CV' legal_name: 'Empresa Ejemplo SA de CV' tax_id: 'EEM010101ABC' rfc: 'EEM010101ABC' tax_system: '601' address: street: 'Av. Reforma' exterior: '123' neighborhood: 'Centro' city: 'Ciudad de MĂ©xico' state: 'CDMX' zip: '06000' country: 'MEX' is_valid: false livemode: false created_at: 1677651234 team: 'team_1234567890' owner: 'user_1234567890' from: 'api' metadata: rfc: 'EEM010101ABC' fiscal_type: 'company' fiscal_status: 'Activo' '201': description: Client created successfully from CSF content: application/json: schema: type: object properties: message: type: string example: 'Client created from CSF' data: $ref: '#/components/schemas/ApiPublicClient' example: message: 'Client created from CSF' data: id: 'client_9876543210' name: 'Nueva Empresa SA de CV' legal_name: 'Nueva Empresa SA de CV' tax_id: 'NEM010101XYZ' rfc: 'NEM010101XYZ' tax_system: '601' address: street: 'Calle Principal' exterior: '456' neighborhood: 'Polanco' city: 'Ciudad de MĂ©xico' state: 'CDMX' zip: '11560' country: 'MEX' is_valid: false livemode: false created_at: 1677651234 team: 'team_1234567890' owner: 'user_1234567890' from: 'api' metadata: rfc: 'NEM010101XYZ' fiscal_type: 'company' fiscal_status: 'Activo' '400': description: Bad Request - Invalid file, missing fiscal data, or client not found content: application/json: schema: $ref: '#/components/schemas/ValidationErrorResponse' examples: no_file: value: message: 'Error processing CSF upload' error: 'No file uploaded' invalid_pdf: value: message: 'Error processing CSF upload' error: 'Could not extract RFC or CIF from PDF' missing_data: value: message: 'Error processing CSF upload' error: 'Missing required fiscal data (name or RFC)' client_not_found: value: message: 'Error processing CSF upload' error: 'Client not found' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' /clients/{id}/stamp-pending-receipts: post: tags: - Clients summary: Stamp pending receipts description: | Stamp all pending receipts for a client. **gigstack Connect:** Stamp other teams' client receipts using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string responses: '200': description: Pending receipts stamped successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /clients/{id}/support-documents: post: tags: - Clients summary: Upload support document description: | Upload a supporting document (contract, proof of delivery, etc.) for a client. **SAT 2026 Compliance:** Documents uploaded to a client are automatically inherited by all of the client's invoices and payments, simplifying compliance management. **gigstack Connect:** Upload documents for other teams' clients using the `team` parameter. **Supported File Types:** - PDF files (.pdf) - Images (.png, .jpg, .jpeg, .webp) **File Size Limit:** 10MB security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string description: 'Client ID' requestBody: required: true content: multipart/form-data: schema: $ref: '#/components/schemas/UploadSupportDocumentInput' responses: '201': description: Document uploaded successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: $ref: '#/components/schemas/SATDocument' message: type: string example: 'Support document uploaded successfully' timestamp: type: string format: date-time '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ValidationErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: Client not found content: application/json: schema: $ref: '#/components/schemas/NotFoundError' get: tags: - Clients summary: List support documents description: | Retrieve all supporting documents attached to a client. **gigstack Connect:** View documents for other teams' clients using the `team` parameter. Documents are returned sorted by creation date (newest first). **Note:** Client documents are automatically inherited by all the client's invoices and payments. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string description: 'Client ID' responses: '200': description: Documents retrieved successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: type: array items: $ref: '#/components/schemas/SATDocument' message: type: string example: 'Support documents retrieved successfully' timestamp: type: string format: date-time '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: Client not found content: application/json: schema: $ref: '#/components/schemas/NotFoundError' # ============================================================================= # SERVICES - Organized by HTTP Method (GET → POST → PUT → DELETE) # ============================================================================= /services: get: tags: - Services summary: List services description: | Retrieve a paginated list of services. **gigstack Connect:** Access other teams' services using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - $ref: '#/components/parameters/LimitParam' - $ref: '#/components/parameters/NextParam' - $ref: '#/components/parameters/OrderByParam' - $ref: '#/components/parameters/SortParam' - $ref: '#/components/parameters/CreatedGteParam' - $ref: '#/components/parameters/CreatedLteParam' responses: '200': description: Services retrieved successfully content: application/json: schema: type: object properties: message: type: string example: 'Services retrieved successfully' data: type: array items: $ref: '#/components/schemas/ApiPublicService' has_more: type: boolean example: false total_results: type: integer example: 10 next: type: string nullable: true example: null example: message: 'Services retrieved successfully' data: - id: 'service_1234567890' description: 'Professional consulting services' sku: 'CONS-001' product_key: '80141503' unit_key: 'E48' unit_name: 'Servicio' unit_price: 1000.0 quantity: 1 taxes: - type: 'IVA' rate: 0.16 factor: 'Tasa' withholding: false team: 'team_1234567890' created_at: 1677651234 from: 'api' has_more: false total_results: 1 post: tags: - Services summary: Create service description: | Create a new service. **gigstack Connect:** Create services for other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ServiceInput' example: description: 'Professional consulting services' sku: 'CONS-001' product_key: '80141503' unit_key: 'ACT' unit_name: 'Actividad' unit_price: 1500.00 taxes: - type: 'IVA' rate: 0.16 factor: 'Tasa' withholding: false inclusive: false responses: '200': description: Service created successfully content: application/json: schema: type: object properties: message: type: string example: 'Service created successfully' data: $ref: '#/components/schemas/ApiPublicService' example: message: 'Service created successfully' data: id: 'service_1234567890' description: 'Professional consulting services' sku: 'CONS-001' product_key: '80141503' unit_key: 'E48' unit_name: 'Servicio' unit_price: 1000.0 quantity: 1 taxes: - type: 'IVA' rate: 0.16 factor: 'Tasa' withholding: false team: 'team_1234567890' created_at: 1677651234 from: 'api' /services/{id}: get: tags: - Services summary: Get service description: | Retrieve a specific service by ID. **gigstack Connect:** Access other teams' services using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string responses: '200': description: Service retrieved successfully content: application/json: schema: type: object properties: message: type: string example: 'Service retrieved successfully' data: $ref: '#/components/schemas/ApiPublicService' example: message: 'Service retrieved successfully' data: id: 'service_1234567890' description: 'Professional consulting services' sku: 'CONS-001' product_key: '80141503' unit_key: 'E48' unit_name: 'Servicio' unit_price: 1000.0 quantity: 1 taxes: - type: 'IVA' rate: 0.16 factor: 'Tasa' withholding: false team: 'team_1234567890' created_at: 1677651234 from: 'api' put: tags: - Services summary: Update service description: | Update an existing service. **gigstack Connect:** Update other teams' services using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ServiceInput' example: description: 'Updated consulting services - Premium package' sku: 'CONS-001-PREMIUM' product_key: '80141503' unit_key: 'ACT' unit_name: 'Actividad' unit_price: 2500.00 taxes: - type: 'IVA' rate: 0.16 factor: 'Tasa' withholding: false inclusive: false responses: '200': description: Service updated successfully content: application/json: schema: type: object properties: message: type: string example: 'Service updated successfully' data: $ref: '#/components/schemas/ApiPublicService' example: message: 'Service updated successfully' data: id: 'service_1234567890' description: 'Professional consulting services' sku: 'CONS-001' product_key: '80141503' unit_key: 'E48' unit_name: 'Servicio' unit_price: 1000.0 quantity: 1 taxes: - type: 'IVA' rate: 0.16 factor: 'Tasa' withholding: false team: 'team_1234567890' created_at: 1677651234 from: 'api' delete: tags: - Services summary: Delete service description: | Delete a specific service. **gigstack Connect:** Delete other teams' services using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string responses: '200': description: Service deleted successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' # ============================================================================= # INVOICES - Organized by HTTP Method (GET → POST → PUT → DELETE) # ============================================================================= /invoices/errors: get: tags: - Invoices summary: List CFDI errors description: | Retrieve a paginated and filterable list of CFDI errors from the error matrix. Use this endpoint to search for error codes, understand error causes, and find solutions. **Query Options:** - Filter by exact error code using `code` parameter - Search across all fields using `q` parameter - Filter by error type (invoice, receiver, sender, unknown) - Paginate results with `limit` and `page` parameters security: - apiKey: [] parameters: - name: code in: query description: Filter by exact error code (e.g., CFDI140223). Returns single document if found. required: false schema: type: string example: CFDI140223 - name: q in: query description: Search query. Searches across code, description, explanation, and solution fields. required: false schema: type: string example: RFC - name: type in: query description: Filter by error type required: false schema: type: string enum: - invoice - receiver - sender - unknown example: receiver - name: limit in: query description: Number of results per page (max 100) required: false schema: type: integer minimum: 1 maximum: 100 default: 50 example: 50 - name: page in: query description: Page number for pagination required: false schema: type: integer minimum: 1 default: 1 example: 1 responses: '200': description: CFDI errors retrieved successfully content: application/json: schema: type: object required: - success - data - total - page - limit - message - timestamp properties: success: type: boolean example: true data: type: array items: $ref: '#/components/schemas/CfdiError' total: type: integer description: Total count of matching errors example: 150 page: type: integer description: Current page number example: 1 limit: type: integer description: Items per page example: 50 message: type: string example: CFDI errors retrieved successfully timestamp: type: number format: int64 description: Unix timestamp in milliseconds example: 1734605400000 examples: singleError: summary: Single error by code value: success: true data: - code: CFDI140223 description: El campo Rfc del receptor no es valido explanation: The RFC (tax ID) provided for the receiver does not meet the validation requirements or format specified by SAT solution: Verify that the receiver's RFC is correct, properly formatted (13 characters for individuals, 12 for legal entities), and matches SAT's registered information type: receiver total: 1 page: 1 limit: 1 message: CFDI error retrieved successfully timestamp: '2025-12-19T10:30:00.000Z' searchResults: summary: Search results value: success: true data: - code: CFDI140223 description: El campo Rfc del receptor no es valido explanation: The RFC (tax ID) provided for the receiver does not meet the validation requirements solution: Verify that the receiver's RFC is correct and properly formatted type: receiver - code: CFDI140225 description: El RFC del receptor no existe en el padron del SAT explanation: The receiver's RFC is not registered in SAT's taxpayer registry solution: Confirm the RFC is registered with SAT or contact the receiver to verify their tax information type: receiver total: 2 page: 1 limit: 10 message: CFDI errors retrieved successfully timestamp: '2025-12-19T10:30:00.000Z' '404': description: Error code not found content: application/json: schema: type: object properties: success: type: boolean example: false message: type: string example: CFDI Error not found error: type: string example: Error code 'INVALID_CODE' not found timestamp: type: number format: int64 description: Unix timestamp in milliseconds example: 1734605400000 '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' /invoices/income: get: tags: - Invoices summary: List income invoices description: | Retrieve a paginated list of income invoices with powerful filtering capabilities. **gigstack Connect:** Access other teams' invoices using the `team` parameter. **Filtering Options:** - Filter by creation date using comparison operators - Filter by metadata fields using dot or underscore notation (e.g., `metadata.order_id` or `metadata_order_id`) security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - $ref: '#/components/parameters/LimitParam' - $ref: '#/components/parameters/NextParam' - $ref: '#/components/parameters/OrderByParam' - $ref: '#/components/parameters/SortParam' - $ref: '#/components/parameters/CreatedGteParam' - $ref: '#/components/parameters/CreatedLteParam' - name: metadata.{key} in: query description: | Filter by any metadata field using dot notation (e.g., `metadata.order_id=ORD-123`) or underscore notation (e.g., `metadata_order_id=ORD-123`). Both formats are supported and equivalent. Uses Typesense search for efficient querying without requiring Firestore indexes. required: false schema: type: string style: form - name: page in: query description: | Page number for pagination when using metadata filters (default 1). Only applies when filtering by metadata fields. required: false schema: type: integer minimum: 1 default: 1 responses: '200': description: Invoices retrieved successfully content: application/json: schema: $ref: '#/components/schemas/ListResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' post: tags: - Invoices summary: Create income invoice description: | Create a new income invoice with CFDI 4.0 compliance. **gigstack Connect:** Create invoices for other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/InvoiceIncomeInput' example: automation_type: 'payment' currency: 'MXN' use: 'P01' payment_form: '03' payment_method: 'PUE' client: id: 'client_1234567890' items: - quantity: 1 description: 'Professional consulting services' sku: 'CONS-001' product_key: '80141503' unit_key: 'ACT' unit_name: 'Actividad' unit_price: 1500.00 taxability: '02' taxes: - type: 'IVA' rate: 0.16 factor: 'Tasa' withholding: false inclusive: false send_email: true emails: ['cliente@empresa.com'] metadata: project_id: 'PROJ-2024-001' department: 'consulting' responses: '200': description: Invoice created successfully content: application/json: schema: type: object properties: message: type: string example: 'Invoice created successfully' data: $ref: '#/components/schemas/ApiPublicIncomeInvoice' example: message: 'Invoice created successfully' data: uuid: 'invoice_1234567890' client: id: 'client_1234567890' name: 'Juan PĂ©rez GarcĂ­a' email: 'juan.perez@ejemplo.com' tax_id: 'PEGJ800101ABC' status: 'stamped' currency: 'MXN' exchange_rate: 1.0 total: 1160.0 subtotal: 1000.0 taxes: 160.0 discount: 0.0 series: 'A' folio_number: 123 invoice_type: 'I' payment_method: 'PUE' items: - id: 'item_1234567890' description: 'Professional consulting services' quantity: 1 unit_price: 1000.0 product_key: '80141503' unit_key: 'E48' created_at: 1677651234 livemode: true owner: 'user_1234567890' '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ValidationErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' /invoices/income/{id}: get: tags: - Invoices summary: Get income invoice description: | Retrieve a specific income invoice by ID. **gigstack Connect:** Access other teams' invoices using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string responses: '200': description: Invoice retrieved successfully content: application/json: schema: type: object properties: message: type: string example: 'Invoice retrieved successfully' data: $ref: '#/components/schemas/ApiPublicIncomeInvoice' example: message: 'Invoice retrieved successfully' data: uuid: 'invoice_1234567890' client: id: 'client_1234567890' name: 'Juan PĂ©rez GarcĂ­a' email: 'juan.perez@ejemplo.com' tax_id: 'PEGJ800101ABC' status: 'stamped' currency: 'MXN' exchange_rate: 1.0 total: 1160.0 subtotal: 1000.0 taxes: 160.0 discount: 0.0 series: 'A' folio_number: 123 invoice_type: 'I' payment_method: 'PUE' verification_url: 'https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx' created_at: 1677651234 livemode: true owner: 'user_1234567890' /invoices/egress: get: tags: - Invoices summary: List egress invoices description: | Retrieve a paginated list of egress invoices with powerful filtering capabilities. **gigstack Connect:** Access other teams' invoices using the `team` parameter. **Filtering Options:** - Filter by creation date using comparison operators - Filter by metadata fields using dot or underscore notation (e.g., `metadata.order_id` or `metadata_order_id`) security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - $ref: '#/components/parameters/LimitParam' - $ref: '#/components/parameters/NextParam' - $ref: '#/components/parameters/OrderByParam' - $ref: '#/components/parameters/SortParam' - $ref: '#/components/parameters/CreatedGteParam' - $ref: '#/components/parameters/CreatedLteParam' - name: metadata.{key} in: query description: | Filter by any metadata field using dot notation (e.g., `metadata.order_id=ORD-123`) or underscore notation (e.g., `metadata_order_id=ORD-123`). Both formats are supported and equivalent. Uses Typesense search for efficient querying without requiring Firestore indexes. required: false schema: type: string style: form - name: page in: query description: | Page number for pagination when using metadata filters (default 1). Only applies when filtering by metadata fields. required: false schema: type: integer minimum: 1 default: 1 responses: '200': description: Invoices retrieved successfully content: application/json: schema: $ref: '#/components/schemas/ListResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' post: tags: - Invoices summary: Create egress invoice description: | Create a new egress invoice (expense/credit note) with CFDI 4.0 compliance. **gigstack Connect:** Create invoices for other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/InvoiceEgressInput' example: automation_type: 'payment' currency: 'MXN' use: 'P01' payment_form: '03' client: id: 'client_1234567890' items: - quantity: 1 description: 'Purchased materials' sku: 'MAT-001' product_key: '80141503' unit_key: 'E48' unit_name: 'Unidad' unit_price: 500.00 taxability: '02' taxes: - type: 'IVA' rate: 0.16 factor: 'Tasa' withholding: false inclusive: false send_email: true emails: ['proveedor@empresa.com'] metadata: purchase_order: 'PO-2024-001' department: 'procurement' responses: '200': description: Invoice created successfully content: application/json: schema: type: object properties: message: type: string example: 'Invoice created successfully' data: $ref: '#/components/schemas/ApiPublicIncomeInvoice' example: message: 'Invoice created successfully' data: uuid: 'invoice_1234567890' client: id: 'client_1234567890' name: 'Proveedor ABC SA' email: 'proveedor@empresa.com' tax_id: 'PABC800101ABC' status: 'stamped' currency: 'MXN' exchange_rate: 1.0 total: 580.0 subtotal: 500.0 taxes: 80.0 discount: 0.0 series: 'E' folio_number: 123 invoice_type: 'E' items: - id: 'item_1234567890' description: 'Purchased materials' quantity: 1 unit_price: 500.0 product_key: '80141503' unit_key: 'E48' created_at: 1677651234 livemode: true owner: 'user_1234567890' '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ValidationErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' /invoices/egress/{id}: get: tags: - Invoices summary: Get egress invoice description: | Retrieve a specific egress invoice by ID. **gigstack Connect:** Access other teams' invoices using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string responses: '200': description: Invoice retrieved successfully content: application/json: schema: type: object properties: message: type: string example: 'Invoice retrieved successfully' data: $ref: '#/components/schemas/ApiPublicIncomeInvoice' example: message: 'Invoice retrieved successfully' data: uuid: 'invoice_1234567890' client: id: 'client_1234567890' name: 'Proveedor ABC SA' email: 'proveedor@empresa.com' tax_id: 'PABC800101ABC' status: 'stamped' currency: 'MXN' exchange_rate: 1.0 total: 580.0 subtotal: 500.0 taxes: 80.0 discount: 0.0 series: 'E' folio_number: 123 invoice_type: 'E' verification_url: 'https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx' created_at: 1677651234 livemode: true owner: 'user_1234567890' /invoices/payment: get: tags: - Invoices summary: List payment complement invoices description: | Retrieve a paginated list of payment complement invoices (CFDI type P - Complemento de Pago). Payment complements are used for PPD (Pago en Parcialidades o Diferido) invoices to register partial or deferred payments. **gigstack Connect:** Access other teams' invoices using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - $ref: '#/components/parameters/LimitParam' - $ref: '#/components/parameters/NextParam' - $ref: '#/components/parameters/OrderByParam' - $ref: '#/components/parameters/SortParam' - $ref: '#/components/parameters/CreatedGteParam' - $ref: '#/components/parameters/CreatedLteParam' responses: '200': description: Payment complement invoices retrieved successfully content: application/json: schema: $ref: '#/components/schemas/ListResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: Forbidden content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' /invoices/payment/{id}: get: tags: - Invoices summary: Get payment complement invoice description: | Retrieve a specific payment complement invoice by ID (CFDI type P - Complemento de Pago). Payment complements contain details about payments made against PPD invoices, including: - Payment amounts and dates - Payment method and form - Related PPD invoices - Tax calculations on payments **gigstack Connect:** Access other teams' invoices using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string responses: '200': description: Payment complement invoice retrieved successfully content: application/json: schema: type: object properties: message: type: string example: 'Invoice retrieved successfully' data: $ref: '#/components/schemas/ApiPublicIncomeInvoice' example: message: 'Invoice retrieved successfully' data: uuid: 'invoice_1234567890' client: id: 'client_1234567890' name: 'Juan PĂ©rez GarcĂ­a' email: 'juan.perez@example.com' tax_id: 'PEGJ800101ABC' status: 'valid' currency: 'XXX' exchange_rate: 1.0 total: 0.0 subtotal: 0.0 taxes: 0.0 discount: 0.0 series: 'CP' folio_number: 456 invoice_type: 'P' payment_method: 'PPD' verification_url: 'https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx' created_at: 1677651234 livemode: true owner: 'user_1234567890' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: Invoice not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' /invoices/{id}/files: get: tags: - Invoices summary: Get invoice files description: | Get XML and PDF files for an invoice. **gigstack Connect:** Access other teams' invoice files using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string - name: file_type in: query required: false schema: type: string enum: ['pdf', 'xml'] description: 'Type of file to retrieve. If not specified, returns both PDF and XML files' responses: '200': description: Invoice files retrieved successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /invoices/{id}/support-documents: post: tags: - Invoices summary: Upload support document description: | Upload a supporting document (contract, proof of delivery, etc.) for an invoice. **SAT 2026 Compliance:** The Mexican tax authority (SAT) can request supporting documentation to validate invoices. This endpoint helps maintain compliance. **gigstack Connect:** Upload documents for other teams' invoices using the `team` parameter. **Supported File Types:** - PDF files (.pdf) - Images (.png, .jpg, .jpeg, .webp) **File Size Limit:** 10MB security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string description: 'Invoice ID' requestBody: required: true content: multipart/form-data: schema: $ref: '#/components/schemas/UploadSupportDocumentInput' responses: '201': description: Document uploaded successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: $ref: '#/components/schemas/SATDocument' message: type: string example: 'Support document uploaded successfully' timestamp: type: string format: date-time '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ValidationErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: Invoice not found content: application/json: schema: $ref: '#/components/schemas/NotFoundError' get: tags: - Invoices summary: List support documents description: | Retrieve all supporting documents attached to an invoice. **gigstack Connect:** View documents for other teams' invoices using the `team` parameter. Documents are returned sorted by creation date (newest first). security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string description: 'Invoice ID' responses: '200': description: Documents retrieved successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: type: array items: $ref: '#/components/schemas/SATDocument' message: type: string example: 'Support documents retrieved successfully' timestamp: type: string format: date-time '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: Invoice not found content: application/json: schema: $ref: '#/components/schemas/NotFoundError' /invoices/{id}: delete: tags: - Invoices summary: Cancel invoice description: | Cancel a specific invoice with SAT. **gigstack Connect:** Cancel other teams' invoices using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: type: object required: - motive properties: motive: type: string maxLength: 2 example: '02' description: 'SAT cancellation motive code (01-04)' substitution_uuid: type: string nullable: true example: '12345678-1234-1234-1234-123456789012' description: 'UUID of the substituting invoice (required for motive 01)' responses: '200': description: Invoice cancelled successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /invoices/search: get: tags: - Invoices summary: Search invoices description: | Full-text search across invoices using Typesense. Provides fast, typo-tolerant search capabilities. **gigstack Connect:** Access other teams' invoices using the `team` parameter. **Search Capabilities:** - Search across client name, email, invoice UUID, description, and metadata - Typo-tolerant fuzzy matching - Paginated results **Requirements:** - Typesense must be configured for your team - The `q` (or `query`) parameter is required security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - $ref: '#/components/parameters/SearchQueryParam' - $ref: '#/components/parameters/SearchQueryBackwardCompatParam' - $ref: '#/components/parameters/LimitParam' - $ref: '#/components/parameters/SearchPageParam' - $ref: '#/components/parameters/FieldsParam' responses: '200': description: Invoices searched successfully content: application/json: schema: type: object required: - message - data - found - page - per_page - success - timestamp properties: message: type: string example: 'Invoices searched successfully' data: type: array items: $ref: '#/components/schemas/ApiPublicIncomeInvoice' found: type: integer description: Total number of results found example: 15 page: type: integer description: Current page number example: 1 per_page: type: integer description: Number of results per page example: 10 success: type: boolean example: true timestamp: type: number format: int64 description: Unix timestamp in milliseconds example: 1677651234000 '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ValidationErrorResponse' examples: missing_query: summary: Missing query parameter value: message: 'Query parameter is required' error: 'missing_query' missing_typesense_key: summary: Typesense not configured value: message: 'Typesense API key not configured for this team' error: 'missing_typesense_key' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' # ============================================================================= # PAYMENTS - Organized by HTTP Method (GET → POST → PUT → DELETE) # ============================================================================= /payments: get: tags: - Payments summary: List payments description: | Retrieve a paginated list of payments with powerful filtering capabilities. **gigstack Connect:** Access other teams' payments using the `team` parameter. **Filtering Options:** - Filter by payment status, currency, amount - Filter by client ID, email, tax ID (RFC), or name - Filter by metadata fields using dot or underscore notation (e.g., `metadata.order_id` or `metadata_order_id`) - Filter by creation date using comparison operators security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - $ref: '#/components/parameters/LimitParam' - $ref: '#/components/parameters/NextParam' - $ref: '#/components/parameters/OrderByParam' - $ref: '#/components/parameters/SortParam' - $ref: '#/components/parameters/CreatedGteParam' - $ref: '#/components/parameters/CreatedLteParam' - $ref: '#/components/parameters/PaymentStatusParam' - $ref: '#/components/parameters/PaymentCurrencyParam' - $ref: '#/components/parameters/PaymentAmountParam' - $ref: '#/components/parameters/PaymentClientIdParam' - $ref: '#/components/parameters/PaymentEmailParam' - $ref: '#/components/parameters/PaymentTaxIdParam' - $ref: '#/components/parameters/PaymentClientNameParam' - name: metadata.{key} in: query description: | Filter by any metadata field using dot notation (e.g., `metadata.order_id=ORD-123`) or underscore notation (e.g., `metadata_order_id=ORD-123`). Both formats are supported and equivalent. required: false schema: type: string style: form responses: '200': description: Payments retrieved successfully content: application/json: schema: $ref: '#/components/schemas/ListResponse' /payments/search: get: tags: - Payments summary: Search payments description: | Full-text search across payments using Typesense. Provides fast, typo-tolerant search capabilities. **gigstack Connect:** Access other teams' payments using the `team` parameter. **Search Capabilities:** - Search across client name, email, payment ID, description, and metadata - Typo-tolerant fuzzy matching - Filter search results by status, currency, or client ID - Paginated results **Requirements:** - Typesense must be configured for your team - The `q` (or `query`) parameter is required security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - $ref: '#/components/parameters/SearchQueryParam' - $ref: '#/components/parameters/SearchQueryBackwardCompatParam' - $ref: '#/components/parameters/LimitParam' - $ref: '#/components/parameters/SearchPageParam' - $ref: '#/components/parameters/FieldsParam' - $ref: '#/components/parameters/PaymentStatusParam' - $ref: '#/components/parameters/PaymentCurrencyParam' - $ref: '#/components/parameters/PaymentClientIdParam' responses: '200': description: Payments searched successfully content: application/json: schema: type: object required: - message - data - found - page - per_page - success - timestamp properties: message: type: string example: 'Payments searched successfully' data: type: array items: $ref: '#/components/schemas/ApiPublicPayment' found: type: integer description: Total number of results found example: 15 page: type: integer description: Current page number example: 1 per_page: type: integer description: Number of results per page example: 10 success: type: boolean example: true timestamp: type: number format: int64 description: Unix timestamp in milliseconds example: 1677651234000 '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ValidationErrorResponse' examples: missing_query: summary: Missing query parameter value: message: 'Query parameter is required' error: 'missing_query' missing_typesense_key: summary: Typesense not configured value: message: 'Typesense API key not configured for this team' error: 'missing_typesense_key' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' /payments/{id}: get: tags: - Payments summary: Get payment description: | Retrieve a specific payment by ID. **gigstack Connect:** Access other teams' payments using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string responses: '200': description: Payment retrieved successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' delete: tags: - Payments summary: Cancel payment description: | Cancel a specific payment. **gigstack Connect:** Cancel other teams' payments using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string responses: '200': description: Payment cancelled successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /payments/request: post: tags: - Payments summary: Request payment description: | Create a payment request that creates a payment in 'requires_payment_method' status. **gigstack Connect:** Create payment requests for other teams using the `team` parameter. ## Payment Request Flow This endpoint creates a payment request that customers can complete using various payment methods. The payment will be created with status 'requires_payment_method'. ## Allowed Payment Methods Control which payment methods are available to the customer: - **`card`**: Credit/debit card payments - **`spei`**: Mexican bank transfer (SPEI) - **`oxxo`**: OXXO convenience store payments - **`stripe-spei`**: Customer balance payments security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RequestPaymentInput' example: client: id: 'client_1234567890' automation_type: 'pue_invoice' currency: 'MXN' exchange_rate: 1.0 allowed_payment_methods: ['card', 'bank', 'oxxo'] items: - id: 'service_1234567890' quantity: 1 unit_price: 1000.00 send_email: true emails: ['customer@example.com'] responses: '200': description: Payment request created successfully content: application/json: schema: type: object properties: message: type: string example: 'Payment request created successfully' data: $ref: '#/components/schemas/ApiPublicPayment' example: message: 'Payment request created successfully' data: id: 'payment_1234567890' client: id: 'client_1234567890' name: 'Juan PĂ©rez GarcĂ­a' email: 'juan.perez@ejemplo.com' tax_id: 'PEGJ800101ABC' status: 'requires_payment_method' currency: 'MXN' exchange_rate: 1.0 allowed_payment_methods: ['card', 'bank', 'oxxo'] short_url: 'https://pay.gigstack.io/p/abc123' total: 1160.0 subtotal: 1000.0 taxes: 160.0 discount: 0.0 items: - id: 'service_1234567890' description: 'Professional consulting services' quantity: 1 unit_price: 1000.0 product_key: '80141503' unit_key: 'E48' emails: ['customer@example.com'] created_at: 1677651234 payment_processor: 'api' livemode: true team: 'team_1234567890' owner: 'user_1234567890' /payments/register: post: tags: - Payments summary: Register payment description: | Register a payment with optional automation for invoice creation. **gigstack Connect:** Register payments for other teams using the `team` parameter. ## Automation Types Control what happens automatically when registering a payment: - **`pue_invoice`**: Creates a PUE (Pago en Una sola ExhibiciĂłn) invoice immediately - **`none`**: No automation, registers payment only ## Payment Form The `payment_form` field specifies the Mexican SAT payment form code: Common codes include: `01` (cash), `02` (check), `03` (electronic transfer), `04` (credit card), etc. The payment will be marked as 'succeeded' immediately upon registration. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RegisterPaymentInput' examples: standard_payment: summary: 'Standard payment without splitting' value: client: id: 'client_1234567890' automation_type: 'pue_invoice' currency: 'MXN' exchange_rate: 1.0 payment_form: '03' items: - id: 'service_1234567890' quantity: 1 unit_price: 1000.00 percentage_split: summary: 'Payment with percentage-based splitting' value: client: id: 'client_1234567890' automation_type: 'pue_invoice' currency: 'MXN' payment_form: '03' items: - id: 'service_1234567890' quantity: 1 unit_price: 1000.00 transfer_data: master: 30 connect: 'EMP800101ABC' master_to: 'client' connect_to: 'master' fixed_commission: summary: 'Payment with fixed commission fee' description: 'Use custom_price to charge a fixed commission instead of percentage' value: client: id: 'client_1234567890' automation_type: 'pue_invoice' currency: 'MXN' payment_form: '03' items: - id: 'service_1234567890' quantity: 1 unit_price: 1000.00 transfer_data: master: 0 connect: 'EMP800101ABC' master_to: 'client' connect_to: 'master' connect_custom_config: custom_price: 50.00 custom_description: 'Platform service fee' responses: '200': description: Payment registered successfully content: application/json: schema: type: object properties: message: type: string example: 'Payment registered successfully' data: oneOf: - $ref: '#/components/schemas/ApiPublicPayment' - type: object description: 'Split payment result' properties: split_reference: type: string example: 'split_abc123xyz' master_payment_id: type: string example: 'payment_master_123' connect_payment_id: type: string example: 'payment_connect_456' master_amount: type: number example: 696.0 connect_amount: type: number example: 464.0 total_amount: type: number example: 1160.0 master_payment: type: object connect_payment: type: object connect_team: type: object nullable: true properties: id: type: string tax_id: type: string legal_name: type: string is_newly_created: type: boolean onboarding_url: type: string examples: standard_payment: summary: 'Standard payment response' value: message: 'Payment registered successfully' data: id: 'payment_1234567890' client: id: 'client_1234567890' name: 'Juan PĂ©rez GarcĂ­a' email: 'juan.perez@ejemplo.com' tax_id: 'PEGJ800101ABC' status: 'succeeded' currency: 'MXN' exchange_rate: 1.0 payment_form: '03' total: 1160.0 subtotal: 1000.0 taxes: 160.0 discount: 0.0 items: - id: 'service_1234567890' description: 'Professional consulting services' quantity: 1 unit_price: 1000.0 product_key: '80141503' unit_key: 'E48' invoices: ['invoice_1234567890'] created_at: 1677651234 succeeded_at: 1677651234 payment_processor: 'api' livemode: true team: 'team_1234567890' owner: 'user_1234567890' split_payment: summary: 'Split payment response' description: 'Response when using transfer_data to split payments' value: message: 'Split payments registered successfully' data: split_reference: 'split_abc123xyz' master_payment_id: 'payment_master_123' connect_payment_id: 'payment_connect_456' master_amount: 696.0 connect_amount: 464.0 total_amount: 1160.0 master_payment: id: 'payment_master_123' client: 'client_1234567890' amount: 696.0 team: 'team_master_123' split_role: 'master' connect_payment: id: 'payment_connect_456' client: 'client_connect_789' amount: 464.0 team: 'team_connect_456' split_role: 'connect' connect_team: id: 'team_connect_456' tax_id: 'EMP800101ABC' legal_name: 'Empresa Ejemplo SA de CV' is_newly_created: true onboarding_url: 'https://api.gigstack.com/onboarding/team_connect_456?token=abc123' '400': description: Bad Request - Invalid payment data or automation type content: application/json: schema: $ref: '#/components/schemas/ValidationErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' /payments/{id}/paid: post: tags: - Payments summary: Mark payment as paid description: | Mark a payment as paid with the specified payment form. **gigstack Connect:** Mark other teams' payments as paid using the `team` parameter. ## Required Information - **payment_form**: SAT-compliant payment form code (01-31, 99) - **date**: Optional timestamp when payment was received security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/MarkPaymentAsPaidInput' example: payment_form: '03' date: 1677651234 responses: '200': description: Payment marked as paid successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /payments/{id}/refund: post: tags: - Payments summary: Refund payment description: | Refund a payment with a specified reason and amount. **gigstack Connect:** Refund other teams' payments using the `team` parameter. ## Key Features - Partial or full refunds supported - Optional external processor refund handling - Automatic refund tracking and reporting - Supports Stripe integration for automatic processor refunds security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RefundPaymentInput' example: reason: 'Customer requested cancellation' amount: 1160.00 external_processor_refund: true responses: '200': description: Payment refunded successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /payments/{id}/support-documents: post: tags: - Payments summary: Upload support document description: | Upload a supporting document (contract, proof of delivery, etc.) for a payment. **SAT 2026 Compliance:** The Mexican tax authority (SAT) can request supporting documentation to validate invoices and payments. This endpoint helps maintain compliance. **gigstack Connect:** Upload documents for other teams' payments using the `team` parameter. **Supported File Types:** - PDF files (.pdf) - Images (.png, .jpg, .jpeg, .webp) **File Size Limit:** 10MB **Document Types:** - `contract`: Service or product contracts - `delivery_proof`: Proof of delivery or service completion - `payment_proof`: Payment receipts or confirmations - `communication`: Emails, messages, or agreements - `payment_confirmation`: Payment processor confirmations - `subscription_info`: Subscription or recurring service details security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string description: 'Payment ID' requestBody: required: true content: multipart/form-data: schema: $ref: '#/components/schemas/UploadSupportDocumentInput' responses: '201': description: Document uploaded successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: $ref: '#/components/schemas/SATDocument' message: type: string example: 'Support document uploaded successfully' timestamp: type: string format: date-time '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ValidationErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: Payment not found content: application/json: schema: $ref: '#/components/schemas/NotFoundError' get: tags: - Payments summary: List support documents description: | Retrieve all supporting documents attached to a payment. **gigstack Connect:** View documents for other teams' payments using the `team` parameter. Documents are returned sorted by creation date (newest first). security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string description: 'Payment ID' responses: '200': description: Documents retrieved successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: type: array items: $ref: '#/components/schemas/SATDocument' message: type: string example: 'Support documents retrieved successfully' timestamp: type: string format: date-time '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: Payment not found content: application/json: schema: $ref: '#/components/schemas/NotFoundError' # ============================================================================= # RECEIPTS - Organized by HTTP Method (GET → POST → DELETE) # ============================================================================= /receipts: get: tags: - Receipts summary: List receipts description: | Retrieve a paginated list of receipts. **gigstack Connect:** View other teams' receipts using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - $ref: '#/components/parameters/LimitParam' - $ref: '#/components/parameters/NextParam' - $ref: '#/components/parameters/OrderByParam' - $ref: '#/components/parameters/SortParam' - $ref: '#/components/parameters/CreatedGteParam' - $ref: '#/components/parameters/CreatedLteParam' responses: '200': description: Receipts retrieved successfully content: application/json: schema: $ref: '#/components/schemas/ListResponse' post: tags: - Receipts summary: Create receipt description: | Create a new receipt with items and client information. Receipts are pre-invoice documents that can be later stamped as CFDI invoices. **Features:** - Automatic amount calculations with taxes - Flexible validity periods - Client auto-creation support - Metadata support for tracking - Idempotency support to prevent duplicate receipts **gigstack Connect:** Create receipts for other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ReceiptInput' example: client: id: 'client_1234567890' currency: 'MXN' items: - id: 'service_1234567890' quantity: 1 periodicity: 'month' payment_form: '03' idempotency_key: 'receipt-key-12345' metadata: order_id: 'ORD-12345' responses: '200': description: Receipt created successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ValidationErrorResponse' /receipts/search: get: tags: - Receipts summary: Search receipts description: | Full-text search across receipts using Typesense. Provides fast, typo-tolerant search capabilities. **gigstack Connect:** Access other teams' receipts using the `team` parameter. **Search Capabilities:** - Search across client name, email, receipt description, and metadata - Typo-tolerant fuzzy matching - Paginated results **Requirements:** - Typesense must be configured for your team - The `q` (or `query`) parameter is required security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - $ref: '#/components/parameters/SearchQueryParam' - $ref: '#/components/parameters/SearchQueryBackwardCompatParam' - $ref: '#/components/parameters/LimitParam' - $ref: '#/components/parameters/SearchPageParam' - $ref: '#/components/parameters/FieldsParam' responses: '200': description: Receipts searched successfully content: application/json: schema: type: object required: - message - data - found - page - per_page - success - timestamp properties: message: type: string example: 'Receipts searched successfully' data: type: array items: type: object description: Receipt object found: type: integer description: Total number of results found example: 15 page: type: integer description: Current page number example: 1 per_page: type: integer description: Number of results per page example: 10 success: type: boolean example: true timestamp: type: number format: int64 description: Unix timestamp in milliseconds example: 1677651234000 '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ValidationErrorResponse' examples: missing_query: summary: Missing query parameter value: message: 'Query parameter is required' error: 'missing_query' missing_typesense_key: summary: Typesense not configured value: message: 'Typesense API key not configured for this team' error: 'missing_typesense_key' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' /receipts/{id}: get: tags: - Receipts summary: Get receipt description: | Retrieve a specific receipt by ID. **gigstack Connect:** View other teams' receipts using the `team` parameter. security: - apiKey: [] parameters: - name: id in: path required: true schema: type: string example: 'receipt_1234567890' description: 'Receipt ID' - $ref: '#/components/parameters/TeamParameter' responses: '200': description: Receipt retrieved successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' '404': description: Receipt not found content: application/json: schema: $ref: '#/components/schemas/NotFoundError' delete: tags: - Receipts summary: Cancel receipt description: | Cancel a receipt. This action cannot be undone. **gigstack Connect:** Cancel other teams' receipts using the `team` parameter. security: - apiKey: [] parameters: - name: id in: path required: true schema: type: string example: 'receipt_1234567890' description: 'Receipt ID' - $ref: '#/components/parameters/TeamParameter' responses: '200': description: Receipt canceled successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /receipts/{id}/stamp: post: tags: - Receipts summary: Stamp receipt description: | Convert a receipt into a CFDI invoice by stamping it with SAT. **Stamp Options:** - `client`: Stamp to the associated client - `general_public_national`: Stamp to Mexican general public - `general_public_foreign`: Stamp to foreign general public **gigstack Connect:** Stamp other teams' receipts using the `team` parameter. security: - apiKey: [] parameters: - name: id in: path required: true schema: type: string example: 'receipt_1234567890' description: 'Receipt ID' - $ref: '#/components/parameters/TeamParameter' requestBody: required: true content: application/json: schema: type: object required: - stamp_to properties: stamp_to: type: string enum: ['client', 'general_public_national', 'general_public_foreign'] example: 'client' description: 'Who to stamp the receipt to' fiscal_information: type: object nullable: true properties: legal_name: type: string nullable: true example: 'Juan PĂ©rez GarcĂ­a' tax_id: type: string nullable: true example: 'PEGJ800101ABC' tax_system: type: string nullable: true example: '601' zip: type: string nullable: true example: '01000' description: 'Custom fiscal information (overrides client data)' date: type: number nullable: true example: 1677651234000 description: 'Custom invoice date (timestamp in milliseconds)' example: stamp_to: 'client' date: 1677651234000 responses: '200': description: Receipt stamped successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/ValidationErrorResponse' # ============================================================================= # TEAMS - Organized by HTTP Method (GET → POST → PUT → DELETE) # ============================================================================= /teams: get: tags: - Teams summary: List teams description: | Retrieve a paginated list of teams. **gigstack Connect:** Access other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - $ref: '#/components/parameters/LimitParam' - $ref: '#/components/parameters/NextParam' - $ref: '#/components/parameters/OrderByParam' - $ref: '#/components/parameters/SortParam' - $ref: '#/components/parameters/CreatedGteParam' - $ref: '#/components/parameters/CreatedLteParam' responses: '200': description: Teams retrieved successfully content: application/json: schema: type: object properties: data: type: array items: $ref: '#/components/schemas/ApiPublicTeam' next: type: string nullable: true description: 'Cursor for next page of results' example: 'team_dmU311Ajzj' total_results: type: number example: 105 has_more: type: boolean example: true message: type: string example: 'Clients retrieved successfully' success: type: boolean example: true timestamp: type: number example: 1768240724433 post: tags: - Teams summary: Create team description: | Create a new team. **gigstack Connect:** Create teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TeamInput' example: address: country: 'MEX' street: 'Av. Reforma' zip: '11000' city: 'Ciudad de MĂ©xico' state: 'CDMX' exterior: '456' municipality: 'Miguel Hidalgo' neighborhood: 'Polanco' brand: alias: 'Empresa Innovadora' primary_color: '#2563eb' secondary_color: '#1d4ed8' logo: 'https://example.com/logo.png' support_email: 'soporte@empresa.com' support_phone: '+52 55 9876 5432' tax_id: 'EIN850123ABC' tax_system: '601' generate_onboarding_url: true add_members: - id: 'user123abc' role: 'editor' - id: 'user456def' role: 'viewer' add_master_team_members: false legal_name: 'Empresa de TecnologĂ­a S.A. de C.V.' credit_limit: 1000 responses: '201': description: Team created successfully content: application/json: schema: type: object properties: message: type: string example: 'Team created successfully' data: allOf: - $ref: '#/components/schemas/ApiPublicTeam' - type: object properties: onboarding_url: type: string nullable: true example: 'https://embeded.gigstack.pro/?sessionId=otpOnboarding_abc123&c=secure_token' description: 'Secure onboarding URL (only present when generate_onboarding_url=true was sent in the request)' /teams/{id}: get: tags: - Teams summary: Get team description: | Retrieve a specific team by ID. **gigstack Connect:** Access other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string responses: '200': description: Team retrieved successfully content: application/json: schema: type: object properties: success: type: boolean example: true data: $ref: '#/components/schemas/ApiPublicTeam' message: type: string example: 'Team retrieved successfully' timestamp: type: string format: date-time example: '2026-01-12T18:00:01.845Z' put: tags: - Teams summary: Update team description: | Update an existing team. **gigstack Connect:** Update other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TeamInput' example: address: country: 'MEX' street: 'Av. Reforma (Updated)' zip: '11000' city: 'Ciudad de MĂ©xico' state: 'CDMX' exterior: '456-B' municipality: 'Miguel Hidalgo' neighborhood: 'Polanco' brand: alias: 'Empresa Innovadora 2025' primary_color: '#1e40af' secondary_color: '#1e3a8a' logo: 'https://example.com/new-logo.png' support_email: 'soporte@empresa.com' support_phone: '+52 55 9876 5432' tax_id: 'EIN850123ABC' tax_system: '601' responses: '200': description: Team updated successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /teams/integrations: get: tags: - Teams summary: Get team integrations description: | Get available integrations for teams. **gigstack Connect:** Access integrations for other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' responses: '200': description: Team integrations retrieved successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /teams/{id}/add-member: post: tags: - Teams summary: Add team member description: | Add a member to a team. **gigstack Connect:** Add members to other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: type: object required: - id properties: id: type: string description: User ID to add as a team member example: 'user123abc' role: type: string description: Role for the team member. Defaults to 'viewer' if not specified. enum: - admin - editor - viewer default: viewer example: 'editor' example: id: 'user123abc' role: 'editor' responses: '200': description: Team member added successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /teams/{id}/remove-member: post: tags: - Teams summary: Remove team member description: | Remove a member from a team. **gigstack Connect:** Remove members from other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: type: object responses: '200': description: Team member removed successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /teams/{id}/series: get: tags: - Teams summary: Get team series description: | Get series for a team. **gigstack Connect:** Get series for other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string responses: '200': description: Team series retrieved successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' post: tags: - Teams summary: Create team series description: | Create a series for a team. **gigstack Connect:** Create series for other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: type: object properties: series: type: string description: 'Series identifier (alphanumeric, max 10 characters)' example: 'B' live: type: number nullable: true description: 'Initial folio number for live mode' default: 0 example: 1000 test: type: number nullable: true description: 'Initial folio number for test mode' default: 0 example: 1 required: - series example: series: 'B' live: 1000 test: 1 responses: '200': description: Team series created successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /teams/{id}/series/{seriesId}: put: tags: - Teams summary: Update team series description: | Update a team series. **gigstack Connect:** Update series for other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string - name: seriesId in: path required: true schema: type: string requestBody: required: true content: application/json: schema: type: object properties: live: type: number nullable: true description: 'Update folio number for live mode' example: 2000 test: type: number nullable: true description: 'Update folio number for test mode' example: 50 description: 'At least one of live or test must be provided' example: live: 2000 responses: '200': description: Team series updated successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /teams/{id}/settings: put: tags: - Teams summary: Update team settings description: | Update team settings including defaults for invoicing, taxes, series, and email configurations. **gigstack Connect:** Update settings for other teams using the `team` parameter. ## Team Settings Configuration This endpoint allows you to configure various team-wide defaults and behaviors: - **Invoice Settings:** Default descriptions, PDF notes, product keys - **Tax Configuration:** Default taxes for MXN and USD currencies - **Email Settings:** BCC recipients, email preferences - **CFDI Configuration:** Default series, uses, product/unit keys - **Automation:** Payment complement automation for PPD invoices security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string description: Team ID example: 'team_1234567890' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TeamSettingsInput' example: keep_full_legal_name: false default_description: 'Professional consulting services' invoice_pdf_notes: 'Thank you for your business' product_key: '80141503' unit_key: 'E48' use: 'P01' periodicity: 'month' emails: invoices_bcc: ['admin@company.com'] avoid_invoice_emails: false default_series: income: serie: 'A' folio_number_live: 1001 folio_number_test: 1 responses: '200': description: Team settings updated successfully content: application/json: schema: allOf: - $ref: '#/components/schemas/StandardSuccessResponse' - type: object properties: message: example: 'Team settings updated' '400': description: Bad Request - Invalid settings data content: application/json: schema: $ref: '#/components/schemas/ValidationErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: Team not found content: application/json: schema: $ref: '#/components/schemas/NotFoundError' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' /teams/{id}/onboarding-url: get: tags: - Teams summary: Get team onboarding URL description: | Generate a secure onboarding URL for team setup and configuration. **Important:** This endpoint is only available for gigstack Connect accounts (master teams). ## Use Cases - Generate onboarding links for new teams - Allow secure team configuration setup - Enable embedded team management flows **gigstack Connect:** Generate onboarding URLs for other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string description: 'Team ID to generate onboarding URL for' responses: '200': description: Onboarding URL generated successfully content: application/json: schema: type: object properties: data: type: string example: 'https://embeded.gigstack.pro/?sessionId=otpOnboarding_abc123&c=secure_token' description: 'Secure onboarding URL with session ID and code' message: type: string example: 'Onboarding URL generated successfully' '401': description: Unauthorized - Only available for master teams content: application/json: schema: type: object properties: message: type: string example: 'Unauthorized' error: type: string example: 'Unauthorized endpoint only available for connect accounts' '404': description: Team not found content: application/json: schema: $ref: '#/components/schemas/NotFoundError' /teams/{id}/sat-connection: post: tags: - Teams summary: Upload SAT CSD certificates description: | Upload SAT CSD (Certificado de Sello Digital) certificates to establish SAT connection for CFDI invoicing. This endpoint accepts multipart form data with the certificate files and password. ## Required Files - **cert**: Certificate file (.cer) - The public certificate - **key**: Private key file (.key) - The encrypted private key - **keyPass**: Password for the private key ## First-Time Connection When this is the first SAT connection for a team (no previous SAT setup), the system will automatically initialize default invoice series (G, NC, P, T). **gigstack Connect:** Upload SAT certificates for other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string description: 'Team ID to upload SAT certificates for' requestBody: required: true content: multipart/form-data: schema: type: object properties: cert: type: string format: binary description: 'Certificate file (.cer)' key: type: string format: binary description: 'Private key file (.key)' keyPass: type: string description: 'Password for the private key' required: - cert - key - keyPass responses: '200': description: SAT connection established successfully content: application/json: schema: allOf: - $ref: '#/components/schemas/StandardSuccessResponse' - type: object properties: data: type: object properties: isValid: type: boolean example: true details: type: object properties: serialNumber: type: string example: '30001000000500003416' validTo: type: number example: 1735689600000 message: example: 'SAT connection established successfully' '400': description: Bad Request - Missing files or invalid certificate content: application/json: schema: $ref: '#/components/schemas/ValidationErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: Forbidden - Team not in same billing account content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Team not found content: application/json: schema: $ref: '#/components/schemas/NotFoundError' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' /teams/{id}/manifest/sign: post: tags: - Teams summary: Sign manifest document description: | Signs a manifest document (Carta Manifiesto) using the FIEL (Firma ElectrĂłnica Avanzada) for SAT compliance. This endpoint is used to sign the authorization manifest that authorizes the PAC (Proveedor Autorizado de CertificaciĂłn) to issue CFDI invoices on behalf of your team's RFC. The manifest must be signed to grant the PAC permission to stamp and process invoices under your team's tax identification. **Important Notes:** - Your SAT configuration must be completed before signing the manifest - The FIEL certificate must be valid and issued by SAT - The certificate must match your team's RFC - Once signed, the manifest is stored in your team's SAT configuration - The manifest includes both XML and PDF files **Supported Formats:** 1. **JSON format (application/json):** - Send Base64 encoded certificate files - Useful for API integrations 2. **Form Data format (multipart/form-data):** - Upload certificate files directly - Useful for web form submissions **Note:** The `team` and `livemode` parameters are automatically extracted from your JWT token and applied to the request. You do not need to include these fields in the request body. security: - apiKey: [] parameters: - name: id in: path required: true schema: type: string description: 'Team ID to sign manifest for' requestBody: required: true content: application/json: schema: type: object required: - key - cert - password properties: key: type: string format: byte description: 'Base64 encoded FIEL .key file' example: 'MIIFDjBABgkqhkiG9w0BBQ0wMz...' cert: type: string format: byte description: 'Base64 encoded FIEL .cer file' example: 'MIIFuzCCA6OgAwIBAgIUMzAwMD...' password: type: string format: password description: 'FIEL password (private key password)' example: 'my_secure_password' examples: basic: summary: Basic manifest signing request value: key: 'MIIFDjBABgkqhkiG9w0BBQ0wMz...' cert: 'MIIFuzCCA6OgAwIBAgIUMzAwMD...' password: 'my_secure_password' multipart/form-data: schema: type: object required: - key - cert - password properties: key: type: string format: binary description: 'FIEL .key file upload' cert: type: string format: binary description: 'FIEL .cer file upload' password: type: string description: 'FIEL password (private key password)' responses: '200': description: Manifest signed successfully content: application/json: schema: type: object properties: message: type: string example: 'Manifest signed successfully' data: type: object properties: xmlBase64: type: string format: byte description: 'Base64 encoded signed manifest XML' pdfBase64: type: string format: byte description: 'Base64 encoded manifest PDF' fechaFirma: type: string format: date-time description: 'Signature date and time' example: '2024-01-08T15:30:00.000Z' mensajeResultado: type: string description: 'Result message from signing service' example: 'Firma exitosa' examples: success: summary: Successful manifest signing value: message: 'Manifest signed successfully' data: xmlBase64: 'PD94bWwgdmVyc2lvbj0iMS4wIi...' pdfBase64: 'JVBERi0xLjQKJeLjz9MKMyAwIG...' fechaFirma: '2024-01-08T15:30:00.000Z' mensajeResultado: 'Firma exitosa' '400': description: Bad Request - Invalid input or validation failed content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: missing_field: summary: Missing required field value: message: 'Bad Request' error: 'key (Base64 encoded .key file) is required' invalid_certificate: summary: Invalid FIEL certificate value: message: 'Bad Request' error: 'Certificado FIEL invĂĄlido' certificate_mismatch: summary: Certificate RFC mismatch value: message: 'Bad Request' error: 'El RFC del certificado (ABC123456XYZ) no coincide con el RFC del equipo (DEF789012ABC)' sat_incomplete: summary: SAT configuration incomplete value: message: 'Bad Request' error: 'SAT configuration is incomplete. Please complete the SAT setup before signing manifests.' signing_failed: summary: Manifest signing failed value: message: 'CFDI Service Error' error: 'Manifest signing failed: El certificado del emisor no es vĂĄlido' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: Team not found content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' examples: team_not_found: summary: Team not found value: message: 'Not Found' error: 'Team not found' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' # ============================================================================= # USERS - Organized by HTTP Method (GET → POST → PUT → DELETE) # ============================================================================= /users: get: tags: - Users summary: List users description: | Retrieve a paginated list of users. **gigstack Connect:** Access other teams' users using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - $ref: '#/components/parameters/LimitParam' - $ref: '#/components/parameters/NextParam' - $ref: '#/components/parameters/OrderByParam' - $ref: '#/components/parameters/SortParam' - $ref: '#/components/parameters/CreatedGteParam' - $ref: '#/components/parameters/CreatedLteParam' responses: '200': description: Users retrieved successfully content: application/json: schema: $ref: '#/components/schemas/ListResponse' post: tags: - Users summary: Create user description: | Create a new user. **gigstack Connect:** Create users for other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UserInput' example: email: 'maria.gonzalez@empresa.com' first_name: 'MarĂ­a' last_name: 'GonzĂĄlez' phone: '+52 55 2345 6789' company_role: 'Gerente de Ventas' address: country: 'MEX' street: 'Calle Morelos' zip: '06000' city: 'Ciudad de MĂ©xico' state: 'CDMX' exterior: '789' neighborhood: 'Centro' auto_join: true role: 'editor' responses: '200': description: User created successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /users/{id}: get: tags: - Users summary: Get user description: | Retrieve a specific user by ID. **gigstack Connect:** Access other teams' users using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string responses: '200': description: User retrieved successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' put: tags: - Users summary: Update user description: | Update an existing user. **gigstack Connect:** Update other teams' users using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UserInput' example: email: 'maria.gonzalez.updated@empresa.com' first_name: 'MarĂ­a Fernanda' last_name: 'GonzĂĄlez LĂłpez' phone: '+52 55 2345 6789' company_role: 'Gerente Regional de Ventas' address: country: 'MEX' street: 'Calle Morelos (Oficina Nueva)' zip: '06000' city: 'Ciudad de MĂ©xico' state: 'CDMX' exterior: '789-A' neighborhood: 'Centro' auto_join: false responses: '200': description: User updated successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /users/reset-password: post: tags: - Users summary: Reset user password description: | Reset a user's password. **gigstack Connect:** Reset passwords for other teams' users using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' requestBody: required: true content: application/json: schema: type: object responses: '200': description: Password reset successfully content: application/json: schema: $ref: '#/components/schemas/StandardSuccessResponse' /users/login-link: post: tags: - Users summary: Generate login link description: | Generate a login link for a user. The link contains a custom Firebase token that allows the user to authenticate directly. **Requirements:** - User must have been created via API (`from: 'api'`) - User must belong to the billing account making the request If requirements are not met, returns a 404 error. **gigstack Connect:** Generate login links for other teams' users using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' requestBody: required: true content: application/json: schema: type: object required: - user_id properties: user_id: type: string description: The Firebase UID of the user example: 'abc123xyz' responses: '200': description: Login link generated successfully content: application/json: schema: type: object properties: data: type: object properties: login_link: type: string description: The login URL with embedded token example: 'https://app.gigstack.pro/auth/token-login?token=eyJhbGc...' valid_until: type: number description: Unix timestamp (ms) when the token expires (1 hour from generation) example: 1732657200000 method: type: string description: The authentication method used enum: [token] example: 'token' message: type: string example: 'Login link generated' '404': description: User not found or not accessible via API content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /webhooks: get: tags: - Webhooks summary: List webhooks description: | Retrieve all configured webhooks for your team. **gigstack Connect:** Access other teams' webhooks using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: limit in: query description: Maximum number of webhooks to return (default 10, max 100) required: false schema: type: integer minimum: 1 maximum: 100 default: 10 - name: status in: query description: Filter webhooks by status required: false schema: type: string enum: [active, inactive] responses: '200': description: Webhooks retrieved successfully content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: 'Webhooks retrieved successfully' data: type: array items: $ref: '#/components/schemas/ApiPublicWebhook' timestamp: type: number example: 1709090576567 example: success: true message: 'Webhooks retrieved successfully' data: - id: 'wh_dyS2ZVTj' url: 'https://webhook.site/7cd05529-40fe-4c98-88e5-761de9c5feb1' events: - payment.created - payment.succeeded - invoice.created status: 'active' description: 'Production payment notifications' owner: '8UWdgXELUhf022vuoq249mtGytG2' created_at: 1709090576567 timestamp: 1709090576567 '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' post: tags: - Webhooks summary: Create webhook description: | Create a new webhook endpoint to receive event notifications. **gigstack Connect:** Create webhooks for other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhookInput' example: url: 'https://your-domain.com/webhooks/gigstack' events: - payment.created - payment.succeeded description: 'Production webhook for payment events' status: 'active' responses: '201': description: Webhook created successfully content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: 'Webhook created successfully' data: $ref: '#/components/schemas/ApiPublicWebhook' example: success: true message: 'Webhook created successfully' data: id: 'wh_dyS2ZVTj' url: 'https://your-domain.com/webhooks/gigstack' events: - payment.created - payment.succeeded status: 'active' description: 'Production webhook for payment events' owner: '8UWdgXELUhf022vuoq249mtGytG2' created_at: 1709090576567 '400': description: Invalid webhook data content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' /webhooks/{id}: get: tags: - Webhooks summary: Get webhook description: | Retrieve details of a specific webhook by ID. **gigstack Connect:** Access other teams' webhooks using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true description: Webhook ID schema: type: string example: 'wh_dyS2ZVTj' responses: '200': description: Webhook retrieved successfully content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: 'Webhook retrieved successfully' data: $ref: '#/components/schemas/ApiPublicWebhook' timestamp: type: number example: 1709090576567 '404': description: Webhook not found content: application/json: schema: $ref: '#/components/schemas/NotFoundError' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' put: tags: - Webhooks summary: Update webhook description: | Update an existing webhook's configuration. All fields are optional. **gigstack Connect:** Update webhooks for other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true description: Webhook ID schema: type: string example: 'wh_dyS2ZVTj' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WebhookUpdateInput' example: status: 'inactive' description: 'Temporarily disabled for maintenance' responses: '200': description: Webhook updated successfully content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: 'Webhook updated successfully' data: $ref: '#/components/schemas/ApiPublicWebhook' '400': description: Invalid webhook data content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Webhook not found content: application/json: schema: $ref: '#/components/schemas/NotFoundError' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' delete: tags: - Webhooks summary: Delete webhook description: | Permanently delete a webhook endpoint. **gigstack Connect:** Delete webhooks for other teams using the `team` parameter. security: - apiKey: [] parameters: - $ref: '#/components/parameters/TeamParameter' - name: id in: path required: true description: Webhook ID schema: type: string example: 'wh_dyS2ZVTj' responses: '200': description: Webhook deleted successfully content: application/json: schema: type: object properties: success: type: boolean example: true message: type: string example: 'Webhook deleted successfully' '404': description: Webhook not found content: application/json: schema: $ref: '#/components/schemas/NotFoundError' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/InternalServerError' tags: - name: gigstack Connect description: | **Multi-Team Resource Access** gigstack Connect enables authorized teams to access and manage resources across multiple teams within the same billing account. ## 🔗 How It Works Add the `team` query parameter to **ANY endpoint** to access another team's resources: ```bash # Access team_xyz789's clients GET /clients?team=team_xyz789 # Create invoice for team_abc123 POST /invoices?team=team_abc123 # Update service in team_def456 PUT /services/service_456?team=team_def456 ``` ## ✅ Requirements - Your API key must belong to a team with gigstack Connect enabled - Target team must share the same billing account - Target team must exist ## ⚠ Error Responses - `401 Unauthorized, not a master team` - gigstack Connect not enabled - `404 Team not found` - Target team doesn't exist - `401 Unauthorized, no matched teams` - Teams don't share billing account ## 🌐 Global Availability The `team` parameter works on **ALL 35+ endpoints** for seamless multi-team management across clients, invoices, payments, services, teams, and users. - name: Clients description: Client management operations with Mexican tax compliance - name: Services description: Service and product catalog management with SAT product keys - name: Invoices description: Invoice management with CFDI 4.0 compliance and SAT integration - name: Payments description: Payment processing, tracking, and refund management - name: Receipts description: Receipt creation and management with CFDI stamping capabilities - name: Teams description: Team management, settings, and member administration - name: Users description: User account management and password operations - name: Webhooks description: Webhook management for real-time event notifications # Apidog-specific extensions x-apidog-folder: 'Gigstack API v2' x-apidog-orders: ['gigstack Connect', 'Clients', 'Services', 'Invoices', 'Payments', 'Receipts', 'Teams', 'Users', 'Webhooks']