openapi: 3.2.0 info: title: Firma Partner Company API description: RESTful API for document signing and template management. version: 01.38.00 contact: name: API Support url: https://firma.com/support servers: - url: https://api.firma.dev/functions/v1/signing-request-api description: Production API - Recommended (Current) - url: https://api.firma.dev/api/v1 description: Production API - Planned security: - ApiKeyAuth: [] tags: - name: Company description: Company information and settings paths: /company: get: summary: Get company information description: Retrieve information about the authenticated company tags: - Company security: - ApiKeyAuth: [] responses: '200': description: Company information retrieved successfully headers: X-RateLimit-Limit: schema: type: integer description: 'Rate limit: 200 requests per minute' X-RateLimit-Remaining: schema: type: integer description: Remaining requests in current window X-RateLimit-Reset: schema: type: integer description: Unix timestamp when rate limit resets content: application/json: schema: $ref: '#/components/schemas/Company' example: id: 123e4567-e89b-12d3-a456-426614174000 name: Acme Corporation language: en account_owner: John Doe account_owner_email: john@acme.com website: https://acme.com icon_url: https://acme.com/logo.png credits: 1000 created_date: '2024-01-15T10:30:00Z' updated_date: '2024-03-20T14:25:00Z' '401': $ref: '#/components/responses/UnauthorizedError' '429': $ref: '#/components/responses/RateLimitError' operationId: getCompany x-codeSamples: - lang: TypeScript label: '@firma-dev/sdk' source: 'import { FirmaClient } from "@firma-dev/sdk"; const firma = new FirmaClient({ apiKey: "YOUR_API_KEY" }); const response = await firma.company.getCompany(); console.log(response);' put: summary: Update company information description: Update all company details. This is a full replacement operation requiring all fields except icon_url. tags: - Company security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object required: - name - account_owner - account_owner_email - website properties: name: type: string maxLength: 255 description: Company name language: type: string enum: - en - es - it - pt - fr - de - el - ru - pl - cs - sv - nl - ro - nb - ca description: Default language for the company account_owner: type: string maxLength: 255 description: Name of the account owner account_owner_email: type: string format: email description: Email address of the account owner website: type: string format: uri description: Company website URL additionalProperties: false example: name: Acme Corporation Ltd account_owner: Jane Smith account_owner_email: jane@acme.com website: https://www.acme.com responses: '200': description: Company updated successfully headers: X-RateLimit-Limit: schema: type: integer description: 'Rate limit: 120 requests per minute' X-RateLimit-Remaining: schema: type: integer description: Remaining requests in current window X-RateLimit-Reset: schema: type: integer description: Unix timestamp when rate limit resets content: application/json: schema: $ref: '#/components/schemas/Company' '400': description: Validation error content: application/json: schema: $ref: '#/components/schemas/Error' examples: protectedFields: summary: Attempted to modify protected fields value: error: 'The following fields cannot be modified: credits' code: VALIDATION_ERROR '401': $ref: '#/components/responses/UnauthorizedError' '429': $ref: '#/components/responses/RateLimitError' operationId: updateCompany x-codeSamples: - lang: TypeScript label: '@firma-dev/sdk' source: "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.updateCompany({\n name: \"Acme Corporation Ltd\",\n account_owner: \"Jane Smith\",\n account_owner_email: \"jane@acme.com\",\n website: \"https://www.acme.com\"\n});\nconsole.log(response);" patch: summary: Partially update company information description: Update specific company fields. Only provided fields will be updated. At least one field must be provided. tags: - Company security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object properties: name: type: string maxLength: 255 description: Company name language: type: string enum: - en - es - it - pt - fr - de - el - ru - pl - cs - sv - nl - ro - nb - ca description: Default language for the company account_owner: type: string maxLength: 255 description: Name of the account owner account_owner_email: type: string format: email description: Email address of the account owner website: type: string format: uri description: Company website URL additionalProperties: false example: name: Acme Corporation Ltd website: https://www.acme.com responses: '200': description: Company updated successfully headers: X-RateLimit-Limit: schema: type: integer description: 'Rate limit: 120 requests per minute' X-RateLimit-Remaining: schema: type: integer description: Remaining requests in current window X-RateLimit-Reset: schema: type: integer description: Unix timestamp when rate limit resets content: application/json: schema: $ref: '#/components/schemas/Company' '400': description: Validation error content: application/json: schema: $ref: '#/components/schemas/Error' examples: protectedFields: summary: Attempted to modify protected fields value: error: 'The following fields cannot be modified: credits' code: VALIDATION_ERROR noFields: summary: No fields provided value: error: Validation failed details: - path: - body message: No fields provided to update invalidEmail: summary: Invalid email value: error: Validation failed details: - path: - account_owner_email message: Invalid email address '401': $ref: '#/components/responses/UnauthorizedError' '429': $ref: '#/components/responses/RateLimitError' operationId: patchCompany x-codeSamples: - lang: TypeScript label: '@firma-dev/sdk' source: "import { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.patchCompany({\n name: \"Acme Corporation Ltd\",\n website: \"https://www.acme.com\"\n});\nconsole.log(response);" /company/settings: get: summary: Get company settings description: Retrieve settings for the authenticated company tags: - Company security: - ApiKeyAuth: [] responses: '200': description: Company settings retrieved successfully content: application/json: schema: $ref: '#/components/schemas/CompanySettings' '401': $ref: '#/components/responses/UnauthorizedError' '404': $ref: '#/components/responses/NotFoundError' '429': $ref: '#/components/responses/RateLimitError' operationId: getCompanySettings x-codeSamples: - lang: TypeScript label: '@firma-dev/sdk' source: 'import { FirmaClient } from "@firma-dev/sdk"; const firma = new FirmaClient({ apiKey: "YOUR_API_KEY" }); const response = await firma.company.getCompanySettings(); console.log(response);' put: summary: Update company settings description: Update company settings. Only provided fields will be updated. tags: - Company security: - ApiKeyAuth: [] requestBody: required: true content: application/json: schema: type: object properties: default_expiration_hours: type: integer minimum: 1 description: Default signing request expiration in hours require_terms_acceptance: type: boolean description: Whether signers must accept terms before signing show_custom_branding_only: type: boolean require_otp_verification: type: boolean allow_presigning_download: type: boolean disable_guided_navigation: type: boolean show_signature_frame: type: boolean show_partial_watermark: type: boolean email_local_part: type: string color_primary: type: - string - 'null' pattern: ^#[0-9A-Fa-f]{6}$ color_primary_fg: type: - string - 'null' pattern: ^#[0-9A-Fa-f]{6}$ color_background: type: - string - 'null' pattern: ^#[0-9A-Fa-f]{6}$ color_foreground: type: - string - 'null' pattern: ^#[0-9A-Fa-f]{6}$ color_card: type: - string - 'null' pattern: ^#[0-9A-Fa-f]{6}$ color_border: type: - string - 'null' pattern: ^#[0-9A-Fa-f]{6}$ color_accent: type: - string - 'null' pattern: ^#[0-9A-Fa-f]{6}$ color_accent_fg: type: - string - 'null' pattern: ^#[0-9A-Fa-f]{6}$ color_canvas: type: - string - 'null' pattern: ^#[0-9A-Fa-f]{6}$ color_muted: type: - string - 'null' pattern: ^#[0-9A-Fa-f]{6}$ color_muted_fg: type: - string - 'null' pattern: ^#[0-9A-Fa-f]{6}$ show_qr_code: type: - boolean - 'null' description: Show a QR code on the signing page that lets signers continue on their phone. This is the company-level default; workspaces, templates, and signing requests can override it. completion_title: type: - string - 'null' description: Company-level default heading for the completion page shown after signing. Null (or an empty string) clears the company default. maxLength: 200 completion_message: type: - string - 'null' description: Company-level default body text for the completion page shown after signing. Null (or an empty string) clears the company default. maxLength: 1000 completion_redirect_url: type: - string - 'null' format: uri description: Company-level default URL the signer is redirected to from the completion page. Must use https://. Null (or an empty string) clears the company default. pattern: ^https:// maxLength: 2000 completion_redirect_delay: type: - integer - 'null' description: Company-level default number of seconds the completion page waits before redirecting (0 redirects immediately). Null clears the company default. minimum: 0 maximum: 30 default_timezone: type: string description: IANA timezone identifier (e.g. "Europe/Paris", "America/New_York"). Set to null to reset to UTC. example: Europe/Paris language: type: string description: Default language for company emails and certificates. enum: - en - es - it - pt - fr - de - el - ru - pl - cs - sv - nl - ro - nb - ca example: en additionalProperties: false responses: '200': description: Company settings updated successfully content: application/json: schema: $ref: '#/components/schemas/CompanySettings' '400': $ref: '#/components/responses/ValidationError' '401': $ref: '#/components/responses/UnauthorizedError' '429': $ref: '#/components/responses/RateLimitError' operationId: updateCompanySettings x-codeSamples: - lang: TypeScript label: '@firma-dev/sdk' source: 'import { FirmaClient } from "@firma-dev/sdk"; const firma = new FirmaClient({ apiKey: "YOUR_API_KEY" }); const response = await firma.company.updateCompanySettings(); console.log(response);' /company/logo: post: tags: - Company summary: Upload Company Logo description: Upload a logo image for the company. Accepts PNG or JPEG, max 2MB. Replaces any existing logo. operationId: uploadCompanyLogo requestBody: required: true content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: Logo image file (PNG or JPEG, max 2MB) required: - file responses: '200': description: Logo uploaded successfully content: application/json: schema: $ref: '#/components/schemas/LogoUploadResponse' '400': description: Invalid file (wrong format, too large, or missing) x-codeSamples: - lang: TypeScript label: '@firma-dev/sdk' source: "import * as fs from \"fs\";\nimport { FirmaClient } from \"@firma-dev/sdk\";\n\nconst firma = new FirmaClient({ apiKey: \"YOUR_API_KEY\" });\n\nconst response = await firma.company.uploadCompanyLogo({\n file: fs.createReadStream(\"/path/to/your/file\")\n});\nconsole.log(response);" delete: tags: - Company summary: Remove Company Logo description: Remove the company logo. Certificates will use the Firma default logo. operationId: deleteCompanyLogo responses: '200': description: Logo removed successfully content: application/json: schema: $ref: '#/components/schemas/LogoDeleteResponse' x-codeSamples: - lang: TypeScript label: '@firma-dev/sdk' source: 'import { FirmaClient } from "@firma-dev/sdk"; const firma = new FirmaClient({ apiKey: "YOUR_API_KEY" }); const response = await firma.company.deleteCompanyLogo(); console.log(response);' components: responses: RateLimitError: description: Too Many Requests - Rate limit exceeded headers: X-RateLimit-Limit: schema: type: integer description: Maximum requests per minute X-RateLimit-Remaining: schema: type: integer description: Requests remaining X-RateLimit-Reset: schema: type: integer description: Unix timestamp of reset Retry-After: schema: type: integer description: Seconds until retry allowed content: application/json: schema: $ref: '#/components/schemas/Error' example: error: Rate Limit Exceeded message: Too many requests. Please wait before retrying. details: retry_after: 45 UnauthorizedError: description: Unauthorized - Invalid or missing API key content: application/json: schema: $ref: '#/components/schemas/Error' example: error: Unauthorized message: Invalid API key ValidationError: description: Bad Request - Validation failed content: application/json: schema: $ref: '#/components/schemas/Error' example: error: Validation Error message: Invalid input data details: name: Name is required email: Invalid email format NotFoundError: description: Not Found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/Error' example: error: Not Found message: The requested resource was not found schemas: LogoDeleteResponse: type: object properties: success: type: boolean description: Logo deletion confirmation required: - success Error: type: object properties: error: type: string description: Human-readable error message code: type: string description: 'Machine-readable error code Seal-related codes: SEALS_DISABLED, SEAL_ALREADY_REVOKED, SEAL_CREATION_DISABLED_EDGE, SEAL_ERASE_NOT_ELIGIBLE, SEAL_IMAGE_INVALID, SEAL_MUTATION_NOT_ALLOWED, SEAL_NOT_FOUND, SEAL_ORDER_COLLISION, SEAL_PAUSED, SEAL_SCOPE_FORBIDDEN, SEAL_UNAVAILABLE' errors: type: array description: All validation errors when multiple failures are reported together. The top-level error repeats the first item for backward compatibility. items: type: object required: - message properties: message: type: string message: type: string description: Detailed error description details: type: object description: Additional error details additionalProperties: true required: - error description: ' Organization Seal error codes: SEALS_DISABLED, SEAL_ALREADY_REVOKED, SEAL_CREATION_DISABLED_EDGE, SEAL_ERASE_NOT_ELIGIBLE, SEAL_IMAGE_INVALID, SEAL_MUTATION_NOT_ALLOWED, SEAL_NOT_FOUND, SEAL_ORDER_COLLISION, SEAL_PAUSED, SEAL_SCOPE_FORBIDDEN, SEAL_UNAVAILABLE' Company: type: object properties: id: type: string format: uuid description: Unique identifier for the company name: type: string description: Company name maxLength: 255 language: type: string description: Default language for the company enum: - en - es - it - pt - fr - de - el - ru - pl - cs - sv - nl - ro - nb - ca default: en account_owner: type: string description: Name of the account owner maxLength: 255 account_owner_email: type: string format: email description: Email address of the account owner website: type: - string - 'null' format: uri description: Company website URL icon_url: type: - string - 'null' format: uri description: Publicly accessible URL to the company logo image. Returns null if no logo is set. example: https://ielmshcswdhuacyjlpiy.supabase.co/functions/v1/logo/company/3feb35a8-5aaf-4603-8b50-acd807176b38 credits: type: integer description: Available credits for the company (read-only, managed internally) minimum: 0 readOnly: true created_date: type: string format: date-time description: Company account creation timestamp updated_date: type: string format: date-time description: Company account last update timestamp required: - id - name - account_owner - account_owner_email - created_date LogoUploadResponse: type: object properties: success: type: boolean icon_url: type: string format: uri description: Public URL to the uploaded logo description: Logo upload confirmation with URL required: - success - icon_url CompanySettings: type: object properties: default_expiration_hours: type: integer minimum: 1 require_terms_acceptance: type: boolean show_custom_branding_only: type: boolean require_otp_verification: type: boolean allow_presigning_download: type: boolean disable_guided_navigation: type: boolean show_signature_frame: type: boolean show_partial_watermark: type: boolean email_local_part: type: string color_primary: type: - string - 'null' color_primary_fg: type: - string - 'null' color_background: type: - string - 'null' color_foreground: type: - string - 'null' color_card: type: - string - 'null' color_border: type: - string - 'null' color_accent: type: - string - 'null' color_accent_fg: type: - string - 'null' color_canvas: type: - string - 'null' color_muted: type: - string - 'null' color_muted_fg: type: - string - 'null' show_qr_code: type: - boolean - 'null' description: Show a QR code on the signing page that lets signers continue on their phone. This is the company-level default; workspaces, templates, and signing requests can override it. completion_title: type: - string - 'null' description: Company-level default heading for the completion page shown after signing. Workspaces, templates, and signing requests can override it. Null means no company default, so the built-in translated heading is used. maxLength: 200 completion_message: type: - string - 'null' description: Company-level default body text for the completion page shown after signing. Workspaces, templates, and signing requests can override it. Null means no company default, so the built-in translated message is used. maxLength: 1000 completion_redirect_url: type: - string - 'null' format: uri description: Company-level default URL the signer is redirected to from the completion page. Must use https://. Workspaces, templates, and signing requests can override it. Null means no redirect unless a lower level sets one. pattern: ^https:// maxLength: 2000 completion_redirect_delay: type: - integer - 'null' description: Company-level default number of seconds the completion page waits before redirecting (0 redirects immediately). Only applies when a redirect URL resolves; the page falls back to 5 seconds when no level sets a delay. minimum: 0 maximum: 30 default_timezone: type: string description: IANA timezone identifier used as the company-wide default for certificates and email timestamps. example: Europe/Paris language: type: string description: Default language for company emails and certificates. enum: - en - es - it - pt - fr - de - el - ru - pl - cs - sv - nl - ro - nb - ca example: en required: - default_expiration_hours securitySchemes: ApiKeyAuth: type: apiKey in: header name: Authorization description: API key for authentication. Use your API key directly without any prefix (e.g., 'your-api-key'). Bearer prefix is optional but not required.