> ## Documentation Index
> Fetch the complete documentation index at: https://docs.terabusinessfinance.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Promote an accepted basic submission to one Application



## OpenAPI

````yaml /openapi.json post /v1/supplier-submissions/{submission_id}/promotion
openapi: 3.1.0
info:
  title: Tera Contracted Supplier API
  version: 1.0.0
  description: >-
    Generated from @tera/validation Supplier Submission Zod contracts. Do not
    hand-edit.
servers:
  - url: https://sandbox-api.terabusinessfinance.com
    description: Live sandbox API. Test credentials only (`tcs_test_`).
  - url: https://api.terabusinessfinance.com
    description: >-
      Intended production host. Live credentials only (`tcs_live_`). Production
      is not yet available: no READY production API deployment, and production
      traffic is disabled.
security: []
tags:
  - name: Submissions
  - name: Corrections
  - name: Promotion
paths:
  /v1/supplier-submissions/{submission_id}/promotion:
    post:
      tags:
        - Promotion
      summary: Promote an accepted basic submission to one Application
      operationId: promoteSupplierSubmission
      parameters:
        - name: submission_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: X-Request-Id
          in: header
          required: false
          description: >-
            Optional caller correlation id. Tera always returns X-Request-Id;
            that header is the only correlation identifier.
          schema:
            type: string
            minLength: 1
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $schema: https://json-schema.org/draft/2020-12/schema
              type: object
              properties:
                first_name:
                  type: string
                  minLength: 1
                  maxLength: 100
                last_name:
                  type: string
                  minLength: 1
                  maxLength: 100
                email:
                  type: string
                  minLength: 1
                  maxLength: 320
                telephone:
                  type: string
                  minLength: 1
                  maxLength: 20
                business_name:
                  type: string
                  minLength: 2
                  maxLength: 200
                business_structure:
                  type: string
                  enum:
                    - limited-company
                    - llp
                    - partnership
                    - sole-trader
                    - other
                business_sector:
                  type: string
                  enum:
                    - construction
                    - transport
                    - manufacturing
                    - motor-trade
                    - retail-wholesale
                    - hospitality
                    - professional-services
                    - healthcare
                    - agriculture
                    - beauty-wellness
                    - facilities
                    - technology-media
                    - education
                    - other
                trading_duration:
                  type: string
                  enum:
                    - less-than-1
                    - 1-2-years
                    - 2-5-years
                    - 5-plus-years
                annual_turnover_range:
                  type: string
                  enum:
                    - under-100k
                    - 100k-250k
                    - 250k-500k
                    - 500k-1m
                    - 1m-5m
                    - over-5m
                funding_amount:
                  type: integer
                  minimum: 1000
                  maximum: 10000000
                funding_purpose:
                  type: string
                  enum:
                    - working-capital
                    - equipment
                    - stock
                    - vehicles
                    - property
                    - tax-vat
                    - acquisition
                    - refinance
                    - other
                funding_purpose_detail:
                  type: string
                  minLength: 1
                  maxLength: 200
                funding_timeframe:
                  type: string
                  enum:
                    - asap
                    - within-1-month
                    - within-3-months
                    - planning-ahead
                preferred_contact_method:
                  type: string
                  enum:
                    - email
                    - phone
                    - either
                company_number:
                  type: string
                  minLength: 1
                  maxLength: 20
                privacy_information:
                  type: object
                  properties:
                    provided:
                      type: boolean
                      const: true
                    wording_version:
                      type: string
                      minLength: 1
                      maxLength: 64
                    captured_at:
                      type: string
                      format: date-time
                      pattern: >-
                        ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
                  required:
                    - provided
                    - wording_version
                    - captured_at
                  additionalProperties: false
                contact_expectation:
                  type: object
                  properties:
                    permission_stated:
                      type: boolean
                      const: true
                    channels:
                      minItems: 1
                      type: array
                      items:
                        type: string
                        enum:
                          - phone
                          - email
                    wording_version:
                      type: string
                      minLength: 1
                      maxLength: 64
                    captured_at:
                      type: string
                      format: date-time
                      pattern: >-
                        ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
                  required:
                    - permission_stated
                    - channels
                    - wording_version
                    - captured_at
                  additionalProperties: false
                marketing:
                  type: boolean
                capture_timestamp:
                  type: string
                  format: date-time
                  pattern: >-
                    ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
                attribution:
                  type: object
                  properties:
                    source:
                      type: string
                      minLength: 1
                      maxLength: 100
                    campaign:
                      type: string
                      minLength: 1
                      maxLength: 100
                    lead_category:
                      type: string
                      minLength: 1
                      maxLength: 100
                  required:
                    - source
                  additionalProperties: false
                stated_collection_basis:
                  type: object
                  properties:
                    stated_basis:
                      type: string
                      minLength: 1
                      maxLength: 200
                    wording_version:
                      type: string
                      minLength: 1
                      maxLength: 64
                  required:
                    - stated_basis
                  additionalProperties: false
                operation_idempotency_key:
                  type: string
                  minLength: 8
                  maxLength: 128
              required:
                - first_name
                - last_name
                - email
                - telephone
                - business_name
                - business_structure
                - business_sector
                - trading_duration
                - annual_turnover_range
                - funding_amount
                - funding_purpose
                - funding_timeframe
                - preferred_contact_method
                - privacy_information
                - contact_expectation
                - marketing
                - capture_timestamp
                - attribution
                - operation_idempotency_key
              additionalProperties: false
      responses:
        '200':
          description: >-
            Current supplier-visible object. Used for identical create replay
            and GET.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SupplierVisibleStatus'
              examples:
                promoted_basic:
                  summary: >-
                    Accepted basic submission after promotion. Level stays
                    basic; Application identifiers are set.
                  value:
                    environment: sandbox
                    submission_id: 11111111-1111-4111-8111-111111111111
                    external_reference: northbridge-enq-1001
                    level: basic
                    status: accepted
                    received_at: '2026-08-29T09:00:00.000Z'
                    decided_at: '2026-08-29T09:12:00.000Z'
                    application_reference: TBF-ABCDEF12
                    application_created_at: '2026-08-29T11:05:00.000Z'
                    billing:
                      billing_status: not_billable
                      billable_at: null
                      billing_model: accepted_submission
                      not_billable_reason: sandbox
        '202':
          description: Validated submission persisted; commercial decision is pending.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SupplierVisibleStatus'
              examples:
                promoted_basic:
                  summary: >-
                    Accepted basic submission after promotion. Level stays
                    basic; Application identifiers are set.
                  value:
                    environment: sandbox
                    submission_id: 11111111-1111-4111-8111-111111111111
                    external_reference: northbridge-enq-1001
                    level: basic
                    status: accepted
                    received_at: '2026-08-29T09:00:00.000Z'
                    decided_at: '2026-08-29T09:12:00.000Z'
                    application_reference: TBF-ABCDEF12
                    application_created_at: '2026-08-29T11:05:00.000Z'
                    billing:
                      billing_status: not_billable
                      billable_at: null
                      billing_model: accepted_submission
                      not_billable_reason: sandbox
        '400':
          description: 'Error codes: bad_request'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SupplierApiError'
              examples:
                bad_request:
                  summary: Malformed JSON or missing required query.
                  value:
                    error:
                      code: bad_request
                      message: Malformed JSON
        '401':
          description: 'Error codes: unauthorized'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SupplierApiError'
              examples:
                unauthorized:
                  summary: Missing or invalid credential.
                  value:
                    error:
                      code: unauthorized
                      message: Authentication failed
        '403':
          description: 'Error codes: forbidden'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SupplierApiError'
              examples:
                forbidden:
                  summary: Valid credential without permission for this operation.
                  value:
                    error:
                      code: forbidden
                      message: Credential is not authorised for this operation
        '404':
          description: 'Error codes: not_found'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SupplierApiError'
              examples:
                not_found:
                  summary: Unknown or cross-tenant submission.
                  value:
                    error:
                      code: not_found
                      message: Submission not found
        '409':
          description: >-
            Error codes: external_reference_conflict, revision_conflict,
            idempotency_conflict, concurrent_promotion
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SupplierApiError'
              examples:
                external_reference_conflict:
                  summary: Same create external_reference with a different body.
                  value:
                    error:
                      code: external_reference_conflict
                      message: external_reference_conflict
                revision_conflict:
                  summary: Contact correction used a stale expected_revision.
                  value:
                    error:
                      code: revision_conflict
                      message: >-
                        Correction revision does not match the current working
                        snapshot
                idempotency_conflict:
                  summary: operation_idempotency_key reused with a different body.
                  value:
                    error:
                      code: idempotency_conflict
                      message: Operation key was reused with a different correction
                concurrent_promotion:
                  summary: Another promotion is already in progress or linked.
                  value:
                    error:
                      code: concurrent_promotion
                      message: Another promotion completed concurrently
        '422':
          description: 'Error codes: validation_error'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SupplierApiError'
              examples:
                validation_error:
                  summary: JSON parsed but failed the level schema.
                  value:
                    error:
                      code: validation_error
                      message: Request does not match the submission contract
                      details:
                        - path: funding_amount
                          message: Minimum amount is £1,000
        '429':
          description: 'Error codes: rate_limited'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
            Retry-After:
              $ref: '#/components/headers/RetryAfter'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SupplierApiError'
              examples:
                rate_limited:
                  summary: Identity, IP, or failed-auth limiter.
                  value:
                    error:
                      code: rate_limited
                      message: Rate limit exceeded. Retry after the Retry-After header.
        '503':
          description: 'Error codes: service_unavailable'
          headers:
            X-Request-Id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SupplierApiError'
              examples:
                service_unavailable:
                  summary: Temporary upstream or platform unavailability.
                  value:
                    error:
                      code: service_unavailable
                      message: Operation could not be completed
      security:
        - SupplierBearer: []
components:
  headers:
    XRequestId:
      description: >-
        Canonical correlation id for this request. Safe to log. Not included in
        the JSON error body.
      schema:
        type: string
    RetryAfter:
      description: Seconds until the client may retry after HTTP 429.
      schema:
        type: integer
        minimum: 1
    RateLimitLimit:
      description: Steady or burst limit for the current bucket.
      schema:
        type: integer
        minimum: 0
    RateLimitRemaining:
      description: Remaining requests in the current window.
      schema:
        type: integer
        minimum: 0
    RateLimitReset:
      description: Unix timestamp when the current window resets.
      schema:
        type: integer
        minimum: 0
  schemas:
    SupplierVisibleStatus:
      $schema: https://json-schema.org/draft/2020-12/schema
      type: object
      properties:
        environment:
          type: string
          enum:
            - sandbox
            - production
        submission_id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
        external_reference:
          type: string
          minLength: 1
          maxLength: 128
        level:
          type: string
          enum:
            - basic
            - application
        status:
          type: string
          enum:
            - received
            - accepted
            - duplicate_not_accepted
            - rejected
        received_at:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
        decided_at:
          anyOf:
            - type: string
              format: date-time
              pattern: >-
                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
            - type: 'null'
        application_reference:
          anyOf:
            - type: string
            - type: 'null'
        application_created_at:
          anyOf:
            - type: string
              format: date-time
              pattern: >-
                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
            - type: 'null'
        billing:
          type: object
          properties:
            billing_status:
              type: string
              enum:
                - pending
                - billable
                - not_billable
            billable_at:
              anyOf:
                - type: string
                  format: date-time
                  pattern: >-
                    ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
                - type: 'null'
            billing_model:
              type: string
              enum:
                - accepted_submission
                - application_created
            not_billable_reason:
              anyOf:
                - type: string
                  enum:
                    - duplicate
                    - rejected
                    - sandbox
                - type: 'null'
          required:
            - billing_status
            - billable_at
            - billing_model
            - not_billable_reason
          additionalProperties: false
      required:
        - environment
        - submission_id
        - external_reference
        - level
        - status
        - received_at
        - decided_at
        - application_reference
        - application_created_at
        - billing
      additionalProperties: false
    SupplierApiError:
      $schema: https://json-schema.org/draft/2020-12/schema
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - bad_request
                - unauthorized
                - forbidden
                - not_found
                - external_reference_conflict
                - revision_conflict
                - idempotency_conflict
                - concurrent_promotion
                - payload_too_large
                - validation_error
                - rate_limited
                - service_unavailable
            message:
              type: string
              minLength: 1
              maxLength: 200
            details: {}
          required:
            - code
            - message
          additionalProperties: false
      required:
        - error
      additionalProperties: false
  securitySchemes:
    SupplierBearer:
      type: http
      scheme: bearer
      description: >-
        Canonical form uses underscore only: tcs_test_<public_id>_<secret> or
        tcs_live_<public_id>_<secret>. Scopes:
        supplier_submissions:create:basic,
        supplier_submissions:create:application, supplier_submissions:read,
        supplier_submissions:correct, supplier_submissions:promote. Effective
        permission is account ∩ credential ∩ environment. HMAC pepper is
        SUPPLIER_API_KEY_PEPPER.

````