Skip to content
Docs
Operation

Create sales channel

POST/sales-channels
Create a sales channel: a policy bundle describing where and under what commercial rules tickets are sold

Headers

Idempotency-KeystringOptional
Makes the write safe to retry. The first request with a key does the work and its response is stored for 24 hours; a repeat with the same key and the same request (method, path, query, X-Ticketlayer-Channel, TL-Version and body) gets that stored status and body back, marked `Idempotent-Replay: true`, without running again. The key is scoped to your organisation and your credential. The same key with a different request is 422 IDEMPOTENCY_KEY_REUSED; a repeat while the first is still running waits for it, then answers 409 IDEMPOTENT_REQUEST_IN_PROGRESS if it has not finished. Only a 2xx is stored: after an error the key is free again. Omit the header and the request behaves as it always has.

Body

accountId*string
name*string
slug*string
descriptionstring
channelType*"website" | "embed" | "box_office" | "kiosk" | "reseller_api" | "internal"
channelTagsstring[]
▼eventFilterobject
mode*"all" | "tagged"
channelTagsstring[]
▼pricingConfigobject
showMemberPricingboolean
showOriginalPriceboolean
includeFeesInPriceboolean
▼customerConfigobject
requireLoginboolean
allowGuestCheckoutboolean
collectPhoneboolean
collectAddressboolean
▼customerFacingobject
enabledboolean
subdomainstring
customDomainstring
allowedOriginsstring (uri) | string[]The browser origins a publishable key on this channel is accepted from (the whole list; a `*` matches one or more characters). Empty accepts any origin; an embed channel must list at least one. Live mints seat map tokens only for a listed origin
magicLinkBaseUrlstring (uri)
▶partnerIdentityobjectA partner trusted to assert who a buyer is (POST /sales/customer-tokens with a partner_assertion proof). Each assertion must name this channel's id as its aud, so two channels trusting the same key cannot use each other's.
priceVisibilityany
reservationTtlSecondsinteger
checkoutTtlSecondsinteger
receivingAccountIdstring
feeProfileIdstring
autoListboolean
sellingRulesany

Returns

Sales channel created successfully

Errors

400
Bad Request - Invalid input
401
Unauthorized - Authentication required
403
Forbidden - Insufficient permissions
404
Not Found - Resource not found
500
Internal Server Error

Every error names its code and links to it. All error codes

curl -X POST "https://api.ticketlayer.com/v1/sales-channels" \  -H "Authorization: Bearer tlak_..." \  -H "X-Ticketlayer-Org: your-org-slug" \  -H "Content-Type: application/json" \  -d '{    "accountId": "string",    "name": "string",    "slug": "string",    "description": "string",    "channelType": "website",    "channelTags": [      "string"    ],    "eventFilter": {      "mode": "all",      "channelTags": [        "string"      ]    },    "pricingConfig": {      "showMemberPricing": true,      "showOriginalPrice": true,      "includeFeesInPrice": true    },    "customerConfig": {      "requireLogin": true,      "allowGuestCheckout": true,      "collectPhone": true,      "collectAddress": true    },    "customerFacing": {      "enabled": true,      "subdomain": "string",      "customDomain": "string",      "allowedOrigins": [        "https://tickets.example.com",        "https://*.example.com"      ],      "magicLinkBaseUrl": "string",      "partnerIdentity": {        "issuer": "string",        "publicKeyPem": "string",        "algorithm": "RS256"      },      "priceVisibility": {        "lockedAs": "hidden",        "unlockHints": true      }    },    "reservationTtlSeconds": 0,    "checkoutTtlSeconds": 0,    "receivingAccountId": "string",    "feeProfileId": "string",    "autoList": true,    "sellingRules": {      "maxTickets": 10,      "singleSeatGap": "warn"    }  }'
Response 201
{
  "channel": {
    "id": "sch_abc123",
    "organisationId": "org_xyz789",
    "accountId": "acc_abc123",
    "name": "Main Website",
    "slug": "main-website",
    "description": "Public web sales",
    "channelType": "website",
    "channelTags": [
      "public"
    ],
    "eventFilter": {
      "mode": "all",
      "channelTags": [
        "summer-festival"
      ]
    },
    "pricingConfig": {
      "showMemberPricing": false,
      "showOriginalPrice": true,
      "includeFeesInPrice": false
    },
    "customerConfig": {
      "requireLogin": false,
      "allowGuestCheckout": true,
      "collectPhone": false,
      "collectAddress": false
    },
    "reservationTtlSeconds": 900,
    "checkoutTtlSeconds": 300,
    "customerFacing": {
      "enabled": true,
      "subdomain": "tickets",
      "customDomain": "tickets.example.com",
      "allowedOrigins": [
        "https://example.com"
      ],
      "magicLinkBaseUrl": "https://tickets.example.com",
      "partnerIdentity": {
        "issuer": "https://partner.example.com",
        "publicKeyPem": "-----BEGIN PUBLIC KEY-----...",
        "algorithm": "RS256"
      },
      "priceVisibility": {
        "lockedAs": "hidden",
        "unlockHints": true
      }
    },
    "receivingAccountId": "acc_abc123",
    "feeProfileId": "sfp_abc123",
    "brandId": "sct_abc123",
    "autoList": false,
    "externalCollection": {
      "enabled": false,
      "methods": []
    },
    "sellingRules": {
      "maxTickets": 10,
      "singleSeatGap": "warn"
    },
    "concierge": {
      "enabled": false,
      "placements": {
        "launcher": true,
        "inline": true,
        "page": true,
        "embedded": {
          "buyTickets": true,
          "checkout": true,
          "myOrders": true,
          "confirmation": true
        }
      },
      "features": {
        "search": true,
        "contact": true,
        "myOrders": true,
        "chat": true
      },
      "ai": {
        "enabled": false,
        "tier": "answer",
        "disabledTools": []
      },
      "persona": {
        "name": "string",
        "avatarAssetId": "string",
        "greeting": "string"
      },
      "openingHours": {
        "timezone": "Europe/London",
        "weekly": {
          "mon": [
            {}
          ],
          "tue": [
            {}
          ],
          "wed": [
            {}
          ],
          "thu": [
            {}
          ],
          "fri": [
            {}
          ],
          "sat": [
            {}
          ],
          "sun": [
            {}
          ]
        }
      },
      "contactQueueId": null,
      "knowledge": {
        "restrictToOwn": true
      },
      "allowedOrigins": [
        "https://tickets.example.com"
      ]
    },
    "isActive": true,
    "isDeleted": false,
    "deletedAt": null,
    "createdAt": "2026-01-15T10:30:00Z",
    "updatedAt": "2026-01-15T10:30:00Z"
  }
}

Try it in test mode

Body