{"openapi":"3.0.0","paths":{"/v1/intl/us/text/checks":{"post":{"description":"Submits text for a compliance check and **returns an ID immediately**; the check runs asynchronously in the background. After you receive the ID, poll `GET {id}` until `status` becomes `completed` or `failed` (usually 3–15 seconds).\n\nThe check evaluates **the English content itself**; the language of the risk explanations is determined by `explainLocale`, and the two do not affect each other. Credits are deducted on submission; if queuing fails, they are refunded in full automatically.","operationId":"textCreate","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntlTextCheckDto"}}}},"responses":{"201":{"description":"Accepted; returns the check ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlAcceptedResponseDto"}}}},"402":{"description":"Insufficient credits"}},"security":[{"ApiKey":[]}],"summary":"Submit a text check","tags":["Text checks"]},"get":{"description":"Returns a paginated list sorted by creation time, newest first, containing summary fields only (the text excerpt is truncated to 100 characters). Only records from this site are returned.","operationId":"textList","parameters":[{"name":"page","required":false,"in":"query","description":"Page number, starting at 1.","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"pageSize","required":false,"in":"query","description":"Number of items per page, up to 50.","schema":{"minimum":1,"maximum":50,"default":20,"type":"number"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Paginated results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlTextCheckListResponseDto"}}}}},"security":[{"ApiKey":[]}],"summary":"List text checks","tags":["Text checks"]}},"/v1/intl/us/text/checks/{id}":{"get":{"description":"When `status` is `processing`, the check is still running; retry later. `risks` holds the final result only when `status` is `completed`.\n\nRisks are reported in two layers that **are kept strictly separate**:\n- `risks` — compliance risks. `kind=violation` is a hard violation; `kind=scene-hint` is a scene hint (a scenario-specific restriction).\n- `customRisks` — matches against the custom rule terms you configured. They are **not counted toward** `riskLevel`; if you configured a replacement, `replacement` is provided.","operationId":"textGetById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Check details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlTextCheckResponseDto"}}}},"404":{"description":"The record does not exist, does not belong to your account, or belongs to another site"}},"security":[{"ApiKey":[]}],"summary":"Get a text check result","tags":["Text checks"]},"delete":{"description":"This action cannot be undone.","operationId":"textRemove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlDeletedResponseDto"}}}},"404":{"description":"The record does not exist or belongs to another site"}},"security":[{"ApiKey":[]}],"summary":"Delete a text check","tags":["Text checks"]}},"/v1/intl/us/text/checks/{id}/fix":{"post":{"description":"Triggers an AI rewrite for a completed check and **returns immediately**; the rewrite runs in the background. Poll `GET {id}`; when the rewrite finishes, the result is in `fixedText` (`fixStatus` becomes `completed`). The rewrite deducts additional credits, which are refunded automatically if it fails.","operationId":"textFix","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"201":{"description":"Accepted; the rewrite runs in the background","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlTextFixAcceptedDto"}}}},"400":{"description":"The record does not need a rewrite (it has no violations), or a rewrite is already in progress"},"402":{"description":"Insufficient credits"},"404":{"description":"The record does not exist or belongs to another site"}},"security":[{"ApiKey":[]}],"summary":"Trigger an AI rewrite","tags":["Text checks"]}},"/v1/intl/us/image/checks":{"post":{"description":"Submits a publicly accessible image URL for a compliance check.\n\nImage checks **complete synchronously**: when this endpoint returns, the result is already available and the response body is the complete check result, so there is no need to poll. (`GET {id}` remains available for later lookups.)\n\n**Always check `status`**: it is normally `completed`; if the engine fails, it is `failed` (in that case the credits have been refunded automatically and `labels` is empty). The endpoint still returns 201 rather than 5xx in this case, because the record itself was created successfully.\n\n**Billing**: 2 credits per image.","operationId":"imageCreate","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntlImageCheckDto"}}}},"responses":{"201":{"description":"Check complete; returns the full result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlImageCheckResponseDto"}}}},"400":{"description":"Invalid parameters"},"402":{"description":"Insufficient credits"}},"security":[{"ApiKey":[]}],"summary":"Submit an image check","tags":["Image checks"]},"get":{"description":"Returns a paginated list sorted by creation time, newest first, containing summary fields only.","operationId":"imageList","parameters":[{"name":"page","required":false,"in":"query","description":"Page number, starting at 1.","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"pageSize","required":false,"in":"query","description":"Number of items per page, up to 50.","schema":{"minimum":1,"maximum":50,"default":20,"type":"number"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Paginated results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlImageCheckListResponseDto"}}}}},"security":[{"ApiKey":[]}],"summary":"List image checks","tags":["Image checks"]}},"/v1/intl/us/image/checks/{id}":{"get":{"description":"Retrieves a previously submitted image check.","operationId":"imageGetById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Check details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlImageCheckResponseDto"}}}},"404":{"description":"The record does not exist or belongs to another site"}},"security":[{"ApiKey":[]}],"summary":"Get an image check result","tags":["Image checks"]},"delete":{"description":"Soft-deletes the check and asynchronously removes the uploaded image file.","operationId":"imageRemove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlDeletedResponseDto"}}}},"404":{"description":"The record does not exist or belongs to another site"}},"security":[{"ApiKey":[]}],"summary":"Delete an image check","tags":["Image checks"]}},"/v1/intl/us/video/checks":{"post":{"description":"Submits a publicly accessible video URL for a compliance check and **returns an ID immediately**; the check runs asynchronously in the background.\nPoll `GET {id}`. A check takes about **half the video's duration** (at least 30 seconds); poll every 5–10 seconds.\n\nThe check covers visual frames (`frames`) and the voiceover (`transcriptRisks`, transcribed and checked by the same engine as text checks).\n**English audio is not moderated as audio**, so `audios` does not report risks; claims made in the voiceover appear in `transcriptRisks`.\n\n**Billing**: 1 credit per second of video, deducted on submission. Report `videoDuration` accurately.","operationId":"videoCreate","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntlVideoCheckDto"}}}},"responses":{"201":{"description":"Accepted; returns the check ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlAcceptedResponseDto"}}}},"402":{"description":"Insufficient credits"}},"security":[{"ApiKey":[]}],"summary":"Submit a video check","tags":["Video checks"]},"get":{"description":"Returns a paginated list sorted by creation time, newest first, containing summary fields only.","operationId":"videoList","parameters":[{"name":"page","required":false,"in":"query","description":"Page number, starting at 1.","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"pageSize","required":false,"in":"query","description":"Number of items per page, up to 50.","schema":{"minimum":1,"maximum":50,"default":20,"type":"number"}},{"name":"status","required":false,"in":"query","description":"Filter by status.","schema":{"enum":["processing","completed","failed"],"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Paginated results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlVideoCheckListResponseDto"}}}}},"security":[{"ApiKey":[]}],"summary":"List video checks","tags":["Video checks"]}},"/v1/intl/us/video/checks/{id}":{"get":{"description":"Each call also advances polling against the check engine by one step, so **you can poll this endpoint directly**; no separate status endpoint is needed.\n\n⚠️ **Polling has two stop conditions**: `status` reaches a terminal state (completed / failed), **and** `transcriptStatus` is no longer `processing`. Voiceover transcription usually finishes after the visual review. If you check only `status`, you will stop while the voiceover is still being transcribed and never receive `transcriptRisks`.\n\n`explainLocale` determines the language used to explain voiceover risks. It is a read-side parameter rather than a submit-side one because results are produced asynchronously, and a language chosen at submission time would not carry through to the time the results are stored.","operationId":"videoGetById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"explainLocale","required":false,"in":"query","description":"Language in which risk explanations are returned. Defaults to zh-CN if omitted.","schema":{"default":"zh-CN","enum":["zh-CN","en-US"],"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Check details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlVideoCheckResponseDto"}}}},"404":{"description":"The record does not exist or belongs to another site"}},"security":[{"ApiKey":[]}],"summary":"Get a video check result","tags":["Video checks"]},"delete":{"description":"Soft-deletes the check and asynchronously removes the uploaded video file.","operationId":"videoRemove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlDeletedResponseDto"}}}},"404":{"description":"The record does not exist or belongs to another site"}},"security":[{"ApiKey":[]}],"summary":"Delete a video check","tags":["Video checks"]}},"/v1/intl/us/batches":{"post":{"description":"Submits multiple text items, images, and videos in a single request, checks them together, and aggregates the verdict. Limits: up to 10 text items, 20 images, and 10 videos, with no more than 40 items per batch in total.\n\n**Returns an ID immediately**; the items are checked in parallel in the background. Poll `GET {id}` for progress: `progress.done / progress.total` shows how far the batch has progressed, and once all items are complete, `result` gives the verdict for the whole batch (PASS / REJECT). Each item includes a `checkId`, which you can pass to the corresponding single-item endpoint to get the full details.\n\n**Billing**: each item is billed at its own unit price (text per item, images per image, videos per second). If your balance is insufficient, the entire batch is rejected at submission.","operationId":"batchCreate","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntlBatchDto"}}}},"responses":{"201":{"description":"Accepted; returns the batch ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlAcceptedResponseDto"}}}},"400":{"description":"The batch is empty or exceeds the per-batch item limit"},"402":{"description":"Insufficient credits to cover the cost of the whole batch"},"403":{"description":"Batch checks require a Premium plan or higher"}},"security":[{"ApiKey":[]}],"summary":"Submit a batch check","tags":["Batch checks"]},"get":{"description":"Returns a paginated list sorted by creation time, newest first, including each batch's progress and verdict. The call also advances the status of a small number of in-progress batches.","operationId":"batchList","parameters":[{"name":"page","required":false,"in":"query","description":"Page number, starting at 1.","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"pageSize","required":false,"in":"query","description":"Number of items per page, up to 50.","schema":{"minimum":1,"maximum":50,"default":20,"type":"number"}},{"name":"explainLocale","required":false,"in":"query","description":"Language in which risk explanations are returned (listing also advances item status, so results may be stored during this call).","schema":{"default":"zh-CN","enum":["zh-CN","en-US"],"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Paginated results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlBatchListResponseDto"}}}}},"security":[{"ApiKey":[]}],"summary":"List batches","tags":["Batch checks"]}},"/v1/intl/us/batches/{id}":{"get":{"description":"Each call also triggers one refresh of item status, so you can poll this endpoint directly. Use `items[].checkId` to get the full details of an individual item.","operationId":"batchGetById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"explainLocale","required":false,"in":"query","description":"Language in which risk explanations are returned. Defaults to zh-CN if omitted.","schema":{"default":"zh-CN","enum":["zh-CN","en-US"],"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Batch details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlBatchResponseDto"}}}},"404":{"description":"The batch does not exist or belongs to another site"}},"security":[{"ApiKey":[]}],"summary":"Get batch progress and results","tags":["Batch checks"]},"delete":{"description":"Soft-deletes the batch and all of its item checks, and asynchronously removes the uploaded image / video files.","operationId":"batchRemove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlDeletedResponseDto"}}}},"404":{"description":"The batch does not exist or belongs to another site"}},"security":[{"ApiKey":[]}],"summary":"Delete a batch","tags":["Batch checks"]}},"/v1/intl/us/custom-rules":{"get":{"description":"Sorted by creation time, newest first, with no pagination. **Only terms on this site are returned**: the same term is stored as a separate entry on each site, and an entry on one site never produces matches on another.","operationId":"customRuleList","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Rule list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlCustomRuleListResponseDto"}}}}},"security":[{"ApiKey":[]}],"summary":"List all custom rules on this site","tags":["Custom rules"]},"post":{"operationId":"customRuleCreate","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntlCustomRuleDto"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlCustomRuleResponseDto"}}}},"400":{"description":"The term already exists on this site, or your plan's word list limit has been reached"},"403":{"description":"Custom rules are a paid feature and are not available on your current plan"}},"security":[{"ApiKey":[]}],"summary":"Create a custom rule","tags":["Custom rules"]}},"/v1/intl/us/custom-rules/quota":{"get":{"description":"Returns the number of terms used and your plan's limit. ⚠️ **`used` is account-wide** (it includes terms you added on other sites), whereas `isPaid` is the subscription status of this site: plans are isolated by site, but word list quota is not.","operationId":"customRuleQuota","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Quota information","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlCustomRuleQuotaDto"}}}}},"security":[{"ApiKey":[]}],"summary":"Get word list quota","tags":["Custom rules"]}},"/v1/intl/us/custom-rules/settings":{"get":{"description":"When off, no custom terms are applied during checks (your data is kept). **The switch is account-wide and is not set per site.**","operationId":"customRuleGetSettings","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Switch status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlCustomRuleSettingsDto"}}}}},"security":[{"ApiKey":[]}],"summary":"Get the master switch status","tags":["Custom rules"]},"patch":{"description":"Independent of each rule's own `enabled` flag: when the master switch is off, per-rule enabled settings have no effect.","operationId":"customRuleSetSettings","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlToggleSettingsDto"}}}},"responses":{"200":{"description":"Updated switch status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlCustomRuleSettingsDto"}}}},"403":{"description":"Custom rules are a paid feature and are not available on your current plan"}},"security":[{"ApiKey":[]}],"summary":"Update the master switch","tags":["Custom rules"]}},"/v1/intl/us/custom-rules/bulk-import":{"post":{"description":"Up to 2000 terms per request. **Idempotency-friendly**: duplicates within the request and terms already in your word list are skipped instead of causing an error, and the response reports three separate counts: `imported` / `skippedDuplicate` / `rejectedQuota`. Terms beyond your quota are rejected; accepted terms are still written as usual.","operationId":"customRuleBulkImport","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlBulkImportDto"}}}},"responses":{"201":{"description":"Import result counts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlCustomRuleImportResultDto"}}}},"403":{"description":"Custom rules are a paid feature and are not available on your current plan"}},"security":[{"ApiKey":[]}],"summary":"Import custom rules in bulk","tags":["Custom rules"]}},"/v1/intl/us/custom-rules/{id}":{"patch":{"description":"Updates only the fields you provide.","operationId":"customRuleUpdate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateIntlCustomRuleDto"}}}},"responses":{"200":{"description":"Updated rule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlCustomRuleResponseDto"}}}},"404":{"description":"The rule does not exist or belongs to another site"}},"security":[{"ApiKey":[]}],"summary":"Update a custom rule","tags":["Custom rules"]},"delete":{"description":"Permanently deletes the rule. This action cannot be undone.","operationId":"customRuleRemove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlDeletedResponseDto"}}}},"404":{"description":"The rule does not exist or belongs to another site"}},"security":[{"ApiKey":[]}],"summary":"Delete a custom rule","tags":["Custom rules"]}},"/v1/intl/us/account":{"get":{"description":"Returns the credit balance, plan, and this month's call counts for each check type on **this site**.\n\n⚠️ Credits and subscriptions are **isolated by site**: the balance here does not include credits you hold on other sites, and vice versa. We recommend calling this endpoint once before you integrate to confirm your balance; otherwise, the only way to find out that your balance is insufficient is to run into a 402.\n\nUsage counts include all entry points (web and API), not only API calls.","operationId":"accountGetAccount","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"responses":{"200":{"description":"Account information","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlAccountResponseDto"}}}}},"security":[{"ApiKey":[]}],"summary":"Get account balance and usage","tags":["Account"]}},"/v1/intl/us/uploads/policy":{"post":{"description":"**You need this endpoint only if you do not have publicly accessible storage for your assets.** If your assets are already in your own object storage or on a CDN, put the URL directly into the check endpoint and skip this step.\n\nReturns POST Policy direct-upload credentials for a standard form upload:\n\n```bash\ncurl -X POST \"$host\" \\\n  -F \"key=$dir<your-filename>\" \\\n  -F \"policy=$policy\" \\\n  -F \"OSSAccessKeyId=$accessKeyId\" \\\n  -F \"signature=$signature\" \\\n  -F \"file=@./promo-01.mp4\"\n```\n\nAfter a successful upload, the asset URL is `{cdnHost}/{key}`; put it in the `videoUrl` / `imageUrl` field of the check endpoint. **The credentials expire after 5 minutes** and allow writes only to the directory prefix dedicated to your account on this site.","operationId":"uploadCreatePolicy","parameters":[{"name":"X-End-Tenant","in":"header","required":false,"description":"The end tenant ID from your own system. When you include it, that tenant's custom rules and check history are kept in a separate isolated scope; credits and the subscription still belong to the account that owns the API key. A tenant is created automatically the first time it appears. Allowed values: 1–64 characters consisting of letters, digits, and _ . : -.","schema":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_.:-]{1,64}$","example":"tenant-4271"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntlUploadPolicyDto"}}}},"responses":{"201":{"description":"Direct-upload credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntlUploadPolicyResponseDto"}}}}},"security":[{"ApiKey":[]}],"summary":"Get direct-upload credentials","tags":["Uploads"]}}},"info":{"title":"ByeRisk Open API · US site","description":"ByeRisk Content Compliance API (US site) — compliance checks for English text, video and images published on TikTok US,\nAmazon and your own store, and in Meta, Google and TikTok ads, plus a custom word list, available to your systems and AI agents.\nThe API uses the same detection engine and the same credit account as the web app.\n\n## Quick start\n\n1. Create a key in [Dashboard → Open API](https://www.byerisk.com/us/open-api). Keys look like `brsk_live_…` and are **shown only once**.\n2. Send `Authorization: Bearer brsk_live_…` with every request.\n3. Submit a check to get an `id`, then poll until `status` is `completed`.\n\n```bash\n# 1) Submit a text check\ncurl -X POST https://www.byerisk.com/api/v1/intl/us/text/checks \\\n  -H \"Authorization: Bearer $BYERISK_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"text\": \"These gummies cure joint pain and are clinically proven to melt belly fat in 7 days. Results guaranteed!\",\n    \"platform\": \"tiktok_us\",\n    \"vertical\": \"supplement\",\n    \"explainLocale\": \"en-US\"\n  }'\n# → { \"success\": true, \"data\": { \"id\": \"cm5abc…\", \"status\": \"processing\" } }\n\n# 2) Poll for the result\ncurl https://www.byerisk.com/api/v1/intl/us/text/checks/cm5abc… \\\n  -H \"Authorization: Bearer $BYERISK_API_KEY\"\n```\n\n## Each key belongs to one site\n\nThis is the most important thing to know before you integrate: **API keys are bound to a site**. A key created in the US site dashboard\ncan call `/v1/intl/us/*` only. Using it on the Indonesia site (`/v1/intl/id/*`) or the China site (`/v1/*`) returns 401, and the reverse is also true.\n\nWithout this binding, the same request could check English text against another site's rule sets (which almost always returns \"pass\"),\nor deduct credits from another site's account. Neither case raises an error; both silently return the wrong answer.\n\nFor the same reason, credits, subscriptions, check history and custom word lists are **all isolated per site**. Balances on other sites cannot be used here.\n\n## Response format\n\nEvery endpoint uses the same envelope: success is `{ \"success\": true, \"data\": … }` and failure is `{ \"success\": false, \"error\": \"…\" }`.\nThe schemas listed for each endpoint below describe the contents of `data`.\n\n## If your own system is multi-tenant\n\nIf you resell ByeRisk or build it into a product used by several of your own customers, add an `X-End-Tenant` header\nwith the tenant ID from your system. We create a separate isolated scope for each tenant:\n\n```bash\ncurl -X POST https://www.byerisk.com/api/v1/intl/us/text/checks \\\n  -H \"Authorization: Bearer $BYERISK_API_KEY\" \\\n  -H \"X-End-Tenant: store-4271\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{ \"text\": \"…\", \"platform\": \"tiktok_us\", \"vertical\": \"general\" }'\n```\n\n- **Data is isolated**: custom word lists, check history and upload directories are kept per tenant and are not visible to other tenants.\n- **The account is not**: credits and the subscription plan stay on your account (the key owner). You do not need to top up each end tenant.\n- A tenant ID is created automatically the first time it appears, **with no registration step**. Allowed values are 1–64 letters, digits, `_`, `.`, `:` and `-`.\n- **Send a stable tenant identifier.** Do not send a value that changes on every request (such as a request ID); that quickly exhausts the per-key limit on isolated scopes.\n\nRate limits apply per **API key**, not per end tenant. Create additional keys if you need more throughput.\n\n## What is checked and what is not\n\n| Dimension | Coverage | Notes |\n|---|---|---|\n| Text | US regulation and platform policy rule library + AI semantic review | Federal rules such as FTC and FDA requirements, plus TikTok Shop, Amazon, and Meta, Google and TikTok ad policies. AI semantic review handles cross-sentence risks and filters false positives. **State laws are not covered** |\n| Images | Visual risks + text recognition on images | Detects prohibited items, and contact details, drug or sexual wording shown on the image |\n| Video | Visual frames + spoken script | The spoken script is transcribed and checked by **the same engine** as text checks. **English audio is not moderated as audio** |\n\n**Image checks do not assess commercial compliance.** They assess the risk of the visuals themselves. They do not verify efficacy claims,\n\"FDA approved\" or certification marks, which require reading and judging the copy on the image. Submit that copy separately as a text check.\n\n**The audio dimension of video checks.** English audio is not moderated as audio, so `audios` does not report risks. Claims made in the voiceover\nappear in `transcriptRisks`, which uses the same rules and AI semantic review as text checks.\n\n## Risk verdicts: two value sets, do not mix them\n\nThis is the most common integration mistake: **`riskLevel` for text checks and for image / video checks is not the same enum**.\n\n| Endpoint | `riskLevel` values | Meaning |\n|---|---|---|\n| Text checks | `safe` / `low` / `medium` / `high` | The highest `severity` among matched violations |\n| Image and video checks | `PASS` / `REVIEW` / `REJECT` | The handling recommendation from content moderation |\n\nThe two come from different assessment pipelines and cannot be converted into each other. Handle them per endpoint rather than defining a single `riskLevel` enum.\n\nEach text risk also has two dimensions:\n\n- `kind` — `violation` is a hard violation that must be fixed; `scene-hint` is a context-dependent note\n- `severity` — `high` / `medium` / `low`. The top-level `riskLevel` is the highest severity among all violations\n\nCustom word list matches are **returned separately in `customRisks`** and do not count toward `riskLevel`; they reflect your own preferences,\nnot a compliance assessment. Terms with a replacement include `replacement`, which you can use for an exact substitution.\n\n## Content language and explanation language are separate\n\nThe content checked is always **English**. The language of risk explanations and suggested fixes is set by `explainLocale`\n(`en-US` or `zh-CN`). **If omitted, it defaults to `zh-CN`, so pass `en-US` explicitly for English explanations.** The two settings are independent:\na team in China selling into the US can read explanations in Chinese while the text being checked stays in English.\n\nThe legal reference (`legalRef`) also follows `explainLocale`. Citations are the same in both languages (for example `21 CFR 101.93`);\nthe Chinese version adds a short explanation in Chinese.\n\n## Asynchronous processing and polling\n\nText, video and batch checks are **asynchronous**: the submit call returns an `id`, and you poll the `GET` endpoint for the result.\nImage checks are synchronous and return the complete result in the submit response.\n\nSuggested polling intervals: 2 seconds for text, 5–10 seconds for video. A video check takes about half the video's duration (at least 30 seconds).\nEach `GET` call also advances the check, so no separate status endpoint is needed.\n\n⚠️ **Video polling has two stop conditions**: `status` has reached a final state **and** `transcriptStatus` is no longer\n`processing`. Transcription usually finishes after visual moderation; if you check `status` alone, you will never receive spoken-script risks.\n\n## Billing\n\nThe API shares this site's credit account with the web app, at the same prices:\n\n| Action | Cost |\n|---|---|\n| Text check | Plan rate, per call |\n| AI rewrite | Plan rate, per call |\n| Video check | 1 credit per second |\n| Image check | 2 credits per image |\n| Custom word list management | Free |\n\nAn insufficient balance returns `402`. You can call `GET /v1/intl/us/account` to check your balance before you start.\n\n## Rate limits\n\nLimits apply per API key, and **each tier is counted separately**: submissions (POST checks and batches) 60 per minute,\nqueries (GET) 600 per minute, and configuration (custom word list management and upload credentials) 120 per minute.\nExceeding a limit returns `429` with a `Retry-After` header. Every response includes `X-RateLimit-Remaining`.\n\n## Error codes\n\n| Code | Meaning |\n|---|---|\n| 400 | Invalid parameters (including a platform, category or explanation language that does not belong to this site) |\n| 401 | The API key is invalid, revoked or expired, **or does not belong to the site you are calling** |\n| 402 | Insufficient credits |\n| 403 | The feature requires a higher plan (API access and batch checks require Premium or above; keys already issued are not affected by changes to this requirement) |\n| 404 | The record does not exist, does not belong to your account, or the site does not exist |\n| 429 | Rate limit exceeded |\n| 500 | Server error; safe to retry |","version":"1.0.0","contact":{}},"tags":[],"servers":[{"url":"https://www.byerisk.com/api","description":"Production"}],"components":{"securitySchemes":{"ApiKey":{"scheme":"bearer","bearerFormat":"JWT","type":"http","description":"An API key created in the dashboard of the corresponding site, in the form brsk_live_…"}},"schemas":{"CreateIntlTextCheckDto":{"type":"object","properties":{"text":{"type":"string","description":"The text to check, 10–5,000 characters. The English content itself is checked, independent of the explanation language below.","minLength":10,"maxLength":5000,"example":"These gummies cure joint pain and are clinically proven to melt belly fat in 7 days. Results guaranteed!"},"platform":{"type":"string","description":"The platform where the content will be published. Determines which platform rule set applies.","enum":["tiktok_us","amazon_us","dtc_us","meta_ads","google_ads","tiktok_ads"],"example":"tiktok_us"},"vertical":{"type":"string","description":"Content category. A specific category applies the rule sets for all categories plus that category's own rule sets; general applies the rule sets of every category (erring on the side of reporting more, with AI semantic review filtering false positives).","enum":["general","beauty","health","supplement","weight_loss","baby","apparel","jewelry","home","pet"],"example":"supplement"},"explainLocale":{"type":"string","description":"The language of risk explanations and suggested fixes. It is independent of the language of the content: the text checked is always English, and this parameter only sets the language used to explain the results. Defaults to zh-CN if omitted; pass en-US for English explanations.","enum":["zh-CN","en-US"],"default":"zh-CN"}},"required":["text","platform","vertical"]},"IntlAcceptedResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"ID of this check, used to poll for the result.","example":"cms8xhc5x0006sp59vrks7zkf"},"object":{"type":"string","description":"Object type.","example":"intl_text_check"},"status":{"type":"string","description":"Current status. It is processing immediately after submission.","example":"processing"}},"required":["id","object","status"]},"IntlTextCheckListItemDto":{"type":"object","properties":{"id":{"type":"string","description":"Check ID."},"object":{"type":"string","description":"Object type.","example":"intl_text_check"},"status":{"type":"string","description":"Status."},"platform":{"type":"string","description":"Publishing platform."},"vertical":{"type":"object","description":"Content category.","nullable":true},"preview":{"type":"string","description":"Text excerpt (truncated to 100 characters). Retrieve the check details for the full text."},"riskLevel":{"type":"string","description":"Top-level verdict.","enum":["safe","low","medium","high"],"nullable":true},"riskCount":{"type":"number","description":"Number of risks."},"fixStatus":{"type":"object","description":"AI rewrite status.","nullable":true},"createdAt":{"type":"object","description":"Creation time."}},"required":["id","object","status","platform","vertical","preview","riskLevel","riskCount","fixStatus","createdAt"]},"IntlTextCheckListResponseDto":{"type":"object","properties":{"object":{"type":"string","description":"Object type. Always list.","example":"list"},"page":{"type":"number","description":"Current page number.","example":1},"pageSize":{"type":"number","description":"Number of items per page.","example":20},"total":{"type":"number","description":"Total number of matching items.","example":128},"hasMore":{"type":"boolean","description":"Whether there is another page.","example":true},"data":{"description":"Items on this page.","type":"array","items":{"$ref":"#/components/schemas/IntlTextCheckListItemDto"}}},"required":["object","page","pageSize","total","hasMore","data"]},"IntlSummaryDto":{"type":"object","properties":{"violation":{"type":"number","description":"Number of hard violations of laws / platform rules.","example":3},"sceneHint":{"type":"number","description":"Number of scene hints.","example":1},"custom":{"type":"number","description":"Number of matches from your custom word list. **Not counted toward** riskLevel.","example":0},"semantic":{"type":"number","description":"Number of semantic risk labels (overall notices that cannot be located at a specific position).","example":2}},"required":["violation","sceneHint"]},"IntlTextRiskDto":{"type":"object","properties":{"id":{"type":"object","description":"Risk ID.","nullable":true},"kind":{"type":"string","description":"Risk kind: `violation` is a hard violation of laws / platform rules (must be fixed); `scene-hint` is a scene hint (a scenario-specific restriction).","enum":["violation","scene-hint"]},"severity":{"type":"string","description":"Severity. The top-level `riskLevel` takes the highest severity among all violations.","enum":["high","medium","low"]},"matchedText":{"type":"string","description":"The matched snippet of the original text.","example":"cure"},"startIndex":{"type":"number","description":"Start index of the matched snippet in the original text. **For semantic matches that cannot be located, this is `-1`** (not null). In that case, search the original text for `matchedText` yourself, or display the risk only as an overall notice.","example":14},"endIndex":{"type":"number","description":"End index of the matched snippet; this can also be `-1`.","example":18},"category":{"type":"object","description":"Risk category, localized according to explainLocale.","nullable":true},"suggestion":{"type":"object","description":"Suggested fix, localized according to explainLocale.","nullable":true},"legalRef":{"type":"object","description":"Legal or platform policy reference, returned in the explainLocale language. Citations are identical in both languages; the Chinese version adds a one-sentence explanation in Chinese.","nullable":true,"example":"21 U.S.C. §343(r)(6); 21 CFR 101.93(f)–(g); FTC Act §12, 15 U.S.C. §52"},"source":{"type":"string","description":"Source of the finding: `rule` is a deterministic rule match; `model` is a model judgment; `custom` is a custom term.","enum":["rule","model","custom"]}},"required":["id","kind","severity","matchedText","startIndex","endIndex","category","suggestion","legalRef","source"]},"IntlCustomRiskDto":{"type":"object","properties":{"matchedText":{"type":"string","description":"The matched snippet of the original text."},"startIndex":{"type":"number","description":"Start index (can be -1)."},"endIndex":{"type":"number","description":"End index (can be -1)."},"replacement":{"type":"object","description":"The replacement you configured for this term. Empty means flag only, with no suggested replacement.","nullable":true},"note":{"type":"object","description":"The note you wrote for this term.","nullable":true}},"required":["matchedText","startIndex","endIndex","replacement","note"]},"IntlTextCheckResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Check ID."},"object":{"type":"string","description":"Object type.","example":"intl_text_check"},"status":{"type":"string","description":"`processing` means the check is still running; retry later. risks holds the final result only when the status is `completed`.","enum":["processing","completed","failed"]},"platform":{"type":"string","description":"Publishing platform.","enum":["tiktok_us","amazon_us","dtc_us","meta_ads","google_ads","tiktok_ads"]},"vertical":{"type":"string","description":"Content category.","enum":["general","beauty","health","supplement","weight_loss","baby","apparel","jewelry","home","pet"]},"text":{"type":"string","description":"The original text that was checked."},"riskLevel":{"type":"string","description":"Top-level verdict, derived from the highest severity among violation risks. ⚠️ This is **not the same set of values** as `PASS` / `REVIEW` / `REJECT` for images and videos.","enum":["safe","low","medium","high"],"nullable":true},"summary":{"description":"Counts by type.","allOf":[{"$ref":"#/components/schemas/IntlSummaryDto"}]},"risks":{"description":"Compliance risks, one entry per risk.","type":"array","items":{"$ref":"#/components/schemas/IntlTextRiskDto"}},"customRisks":{"description":"Matches from your custom word list. **Separate from risks and not counted toward riskLevel**: they reflect your own preferences, not a compliance judgment.","type":"array","items":{"$ref":"#/components/schemas/IntlCustomRiskDto"}},"semanticLabels":{"description":"Overall notices for risks that the model identified but could not locate in a specific snippet.","type":"array","items":{"type":"string"}},"fixStatus":{"type":"object","description":"AI rewrite status: null = not triggered | processing = rewrite in progress | completed = finished | failed = failed.","nullable":true},"fixedText":{"type":"object","description":"Full text after the AI rewrite. Populated only after the rewrite completes.","nullable":true},"createdAt":{"type":"object","description":"Creation time (ISO 8601)."},"updatedAt":{"type":"object","description":"Last update time (ISO 8601)."}},"required":["id","object","status","platform","vertical","text","riskLevel","summary","risks","customRisks","semanticLabels","fixStatus","fixedText","createdAt","updatedAt"]},"IntlTextFixAcceptedDto":{"type":"object","properties":{"id":{"type":"string","description":"Check ID."},"object":{"type":"string","description":"Object type.","example":"intl_text_check"},"fixStatus":{"type":"string","description":"Rewrite status. It is processing once the request is accepted.","example":"processing"},"creditCost":{"type":"number","description":"Credits consumed by this rewrite.","example":2}},"required":["id","object","fixStatus"]},"IntlDeletedResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"ID of the deleted record."},"object":{"type":"string","description":"Object type.","example":"intl_text_check"},"deleted":{"type":"boolean","description":"Always true.","example":true}},"required":["id","object","deleted"]},"CreateIntlImageCheckDto":{"type":"object","properties":{"imageUrl":{"type":"string","description":"Image URL. It must be publicly accessible (our check service must be able to fetch it directly). If you do not have your own object storage, first call `POST /v1/intl/{country}/uploads/policy` to get direct-upload credentials.","example":"https://cdn.example.com/products/serum-01.jpg"},"imageTitle":{"type":"string","description":"Image title / file name, used to identify the image in your history.","example":"serum-01.jpg"},"imageSize":{"type":"number","description":"Image size in bytes.","example":254112,"minimum":1},"imageWidth":{"type":"number","description":"Image width in pixels.","example":1080},"imageHeight":{"type":"number","description":"Image height in pixels.","example":1080},"vertical":{"type":"string","description":"Declared content category. **It does not affect the visual assessment for this check** (the visual policy is tied to account-side configuration and is independent of category); it is used only for record-keeping and for display in your history. Fill it in accurately, or leave it empty.","enum":["general","beauty","health","supplement","weight_loss","baby","apparel","jewelry","home","pet"]},"explainLocale":{"type":"string","description":"Language in which risk labels are returned. Same as for text checks; unrelated to the language of any text in the image.","enum":["zh-CN","en-US"],"default":"zh-CN"}},"required":["imageUrl","imageTitle","imageSize"]},"IntlImageFileDto":{"type":"object","properties":{"url":{"type":"string","description":"Image URL (the one you submitted)."},"title":{"type":"string","description":"Image title / file name."},"sizeBytes":{"type":"object","description":"Size in bytes.","nullable":true},"width":{"type":"object","description":"Width in pixels.","nullable":true},"height":{"type":"object","description":"Height in pixels.","nullable":true}},"required":["url","title","sizeBytes","width","height"]},"IntlImageLabelDto":{"type":"object","properties":{"description":{"type":"string","description":"Risk label, localized according to explainLocale.","example":"Sexual content"},"riskLevel":{"type":"string","description":"This label's own risk level. Older records have no per-label risk level; in that case this is null (no value is made up).","enum":["PASS","REVIEW","REJECT"],"nullable":true}},"required":["description","riskLevel"]},"IntlImageCheckResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Check ID."},"object":{"type":"string","description":"Object type.","example":"intl_image_check"},"status":{"type":"string","description":"**Always check this field**: if the engine fails, it is `failed` (credits have been refunded automatically and labels is empty), and the endpoint still returns 201.","enum":["processing","completed","failed"]},"image":{"description":"Image information.","allOf":[{"$ref":"#/components/schemas/IntlImageFileDto"}]},"vertical":{"type":"string","description":"Category declared at submission. Recorded only; it **does not affect the visual assessment**.","enum":["general","beauty","health","supplement","weight_loss","baby","apparel","jewelry","home","pet"],"nullable":true},"riskLevel":{"type":"string","description":"Top-level verdict. ⚠️ This is **not the same set of values** as safe/low/medium/high for text checks.","enum":["PASS","REVIEW","REJECT"],"nullable":true},"labels":{"description":"Matched risk labels. An empty array when there are no risks.","type":"array","items":{"$ref":"#/components/schemas/IntlImageLabelDto"}},"createdAt":{"type":"object","description":"Creation time."},"updatedAt":{"type":"object","description":"Last update time."}},"required":["id","object","status","image","vertical","riskLevel","labels","createdAt","updatedAt"]},"IntlImageCheckListItemDto":{"type":"object","properties":{"id":{"type":"string","description":"Check ID."},"object":{"type":"string","description":"Object type.","example":"intl_image_check"},"status":{"type":"string","description":"Status."},"image":{"type":"object","description":"Image URL and title."},"vertical":{"type":"object","description":"Declared category.","nullable":true},"riskLevel":{"type":"string","description":"Top-level verdict.","enum":["PASS","REVIEW","REJECT"],"nullable":true},"labels":{"description":"Risk label text (the list does not include per-label risk levels).","type":"array","items":{"type":"string"}},"createdAt":{"type":"object","description":"Creation time."}},"required":["id","object","status","image","vertical","riskLevel","labels","createdAt"]},"IntlImageCheckListResponseDto":{"type":"object","properties":{"object":{"type":"string","description":"Object type. Always list.","example":"list"},"page":{"type":"number","description":"Current page number.","example":1},"pageSize":{"type":"number","description":"Number of items per page.","example":20},"total":{"type":"number","description":"Total number of matching items.","example":128},"hasMore":{"type":"boolean","description":"Whether there is another page.","example":true},"data":{"description":"Items on this page.","type":"array","items":{"$ref":"#/components/schemas/IntlImageCheckListItemDto"}}},"required":["object","page","pageSize","total","hasMore","data"]},"CreateIntlVideoCheckDto":{"type":"object","properties":{"videoUrl":{"type":"string","description":"Video URL. It must be publicly accessible. If you do not have your own object storage, first call the direct-upload credentials endpoint.","example":"https://cdn.example.com/videos/promo-01.mp4"},"videoTitle":{"type":"string","description":"Video title / file name.","example":"promo-01.mp4"},"videoSize":{"type":"number","description":"Video size in **MB** (not bytes). Maximum 1024 (1GB).","example":12.4,"minimum":0.01,"maximum":1024},"videoDuration":{"type":"number","description":"Video duration in seconds. **Billing is based on this value** (1 credit per second), so report it accurately.","example":45,"minimum":1},"videoWidth":{"type":"number","description":"Video width in pixels.","example":1080},"videoHeight":{"type":"number","description":"Video height in pixels.","example":1920},"platform":{"type":"string","description":"Publishing platform. It determines only which platform rule set applies to the **voiceover**; if omitted, this site's default platform is used.","enum":["tiktok_us","amazon_us","dtc_us","meta_ads","google_ads","tiktok_ads"]},"vertical":{"type":"string","description":"Content category. It determines only which category rule sets apply to the **voiceover**: a specific category applies the rule sets for all categories plus that category's own rule sets; if omitted or general, the rule sets of every category apply (erring on the side of reporting more). It has no effect on the visual or audio assessment.","enum":["general","beauty","health","supplement","weight_loss","baby","apparel","jewelry","home","pet"]}},"required":["videoUrl","videoTitle","videoSize","videoDuration"]},"IntlVideoCheckListItemDto":{"type":"object","properties":{"id":{"type":"string","description":"Check ID."},"object":{"type":"string","description":"Object type.","example":"intl_video_check"},"status":{"type":"string","description":"Video review status."},"video":{"type":"object","description":"Video URL, title, and duration."},"vertical":{"type":"object","description":"Declared category.","nullable":true},"riskLevel":{"type":"string","description":"Top-level verdict.","enum":["PASS","REVIEW","REJECT"],"nullable":true},"labels":{"description":"Risk labels.","type":"array","items":{"type":"string"}},"transcriptStatus":{"type":"object","description":"Voiceover transcription status.","nullable":true},"createdAt":{"type":"object","description":"Creation time."}},"required":["id","object","status","video","vertical","riskLevel","labels","transcriptStatus","createdAt"]},"IntlVideoCheckListResponseDto":{"type":"object","properties":{"object":{"type":"string","description":"Object type. Always list.","example":"list"},"page":{"type":"number","description":"Current page number.","example":1},"pageSize":{"type":"number","description":"Number of items per page.","example":20},"total":{"type":"number","description":"Total number of matching items.","example":128},"hasMore":{"type":"boolean","description":"Whether there is another page.","example":true},"data":{"description":"Items on this page.","type":"array","items":{"$ref":"#/components/schemas/IntlVideoCheckListItemDto"}}},"required":["object","page","pageSize","total","hasMore","data"]},"IntlVideoFileDto":{"type":"object","properties":{"url":{"type":"string","description":"Video URL."},"title":{"type":"string","description":"Video title / file name."},"sizeMb":{"type":"object","description":"Size (MB).","nullable":true},"durationSeconds":{"type":"object","description":"Duration (seconds).","nullable":true},"width":{"type":"object","description":"Width in pixels.","nullable":true},"height":{"type":"object","description":"Height in pixels.","nullable":true}},"required":["url","title","sizeMb","durationSeconds","width","height"]},"IntlVideoFrameDto":{"type":"object","properties":{"timeSeconds":{"type":"number","description":"Timestamp of the flagged frame in the video, in seconds.","example":12},"riskLevel":{"type":"string","description":"Risk level of this frame.","enum":["PASS","REVIEW","REJECT"],"nullable":true},"description":{"type":"string","description":"Description of the finding."},"imageUrl":{"type":"object","description":"Screenshot URL of the flagged frame. **This is a short-lived signed URL and will expire**; to keep it long term, copy the file to your own storage.","nullable":true},"ocrText":{"type":"object","description":"Text recognized in the frame.","nullable":true}},"required":["timeSeconds","riskLevel","description","imageUrl","ocrText"]},"IntlVideoAudioDto":{"type":"object","properties":{"startSeconds":{"type":"number","description":"Start of the flagged segment, in seconds."},"endSeconds":{"type":"number","description":"End of the flagged segment, in seconds."},"riskLevel":{"type":"string","description":"Risk level of this segment.","enum":["PASS","REVIEW","REJECT"],"nullable":true},"description":{"type":"string","description":"Description of the finding."},"text":{"type":"object","description":"Transcribed speech of the flagged segment.","nullable":true}},"required":["startSeconds","endSeconds","riskLevel","description","text"]},"IntlTranscriptRiskDto":{"type":"object","properties":{"matchedText":{"type":"string","description":"The matched snippet of the voiceover."},"severity":{"type":"string","description":"Severity.","enum":["high","medium","low"]},"category":{"type":"object","description":"Risk category, localized.","nullable":true},"suggestion":{"type":"object","description":"Suggested fix, localized.","nullable":true},"legalRef":{"type":"object","description":"Legal reference, returned in the explainLocale language (citations are identical in both languages).","nullable":true},"replacement":{"type":"object","description":"Compliant wording that can directly replace matchedText; empty means the snippet can only be removed.","nullable":true},"startSeconds":{"type":"number","description":"Start of the sentence containing the match, in seconds. You can use it directly to seek."},"endSeconds":{"type":"number","description":"End of the sentence containing the match, in seconds."},"sentence":{"type":"object","description":"The full sentence containing the match, for context.","nullable":true},"source":{"type":"string","description":"Source of the finding.","enum":["rule","model","custom"]}},"required":["matchedText","severity","category","suggestion","legalRef","replacement","startSeconds","endSeconds","sentence","source"]},"IntlVideoCheckResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Check ID."},"object":{"type":"string","description":"Object type.","example":"intl_video_check"},"status":{"type":"string","description":"Video review status. ⚠️ **It is not the only stop condition for polling**: you must also check `transcriptStatus`, because voiceover transcription usually finishes after the visual review.","enum":["processing","completed","failed"]},"video":{"description":"Video information.","allOf":[{"$ref":"#/components/schemas/IntlVideoFileDto"}]},"platform":{"type":"string","description":"Platform used to check the voiceover.","enum":["tiktok_us","amazon_us","dtc_us","meta_ads","google_ads","tiktok_ads"],"nullable":true},"vertical":{"type":"string","description":"Category used to check the voiceover.","enum":["general","beauty","health","supplement","weight_loss","baby","apparel","jewelry","home","pet"],"nullable":true},"riskLevel":{"type":"string","description":"Top-level verdict (visuals + audio).","enum":["PASS","REVIEW","REJECT"],"nullable":true},"labels":{"description":"Overall risk labels.","type":"array","items":{"type":"string"}},"frames":{"description":"Visual findings, with timestamps in seconds.","type":"array","items":{"$ref":"#/components/schemas/IntlVideoFrameDto"}},"audios":{"description":"Audio findings, with start and end times in seconds.","type":"array","items":{"$ref":"#/components/schemas/IntlVideoAudioDto"}},"transcript":{"type":"object","description":"Full transcript of the voiceover.","nullable":true},"transcriptStatus":{"type":"object","description":"Voiceover transcription status: `null` = not enabled | `processing` = transcribing | `completed` | `failed` | `empty` = no audio track. **While it is processing, voiceover risks are not yet complete; keep polling.**","nullable":true},"transcriptRisks":{"description":"Voiceover violations. They are checked by the same engine as text checks and count toward the verdict on an equal footing with visual and audio findings.","type":"array","items":{"$ref":"#/components/schemas/IntlTranscriptRiskDto"}},"createdAt":{"type":"object","description":"Creation time."},"updatedAt":{"type":"object","description":"Last update time."}},"required":["id","object","status","video","platform","vertical","riskLevel","labels","frames","audios","transcript","transcriptStatus","transcriptRisks","createdAt","updatedAt"]},"IntlBatchImageDto":{"type":"object","properties":{"url":{"type":"string","description":"Image URL, publicly accessible."},"name":{"type":"string","description":"Image title / file name."},"size":{"type":"number","description":"Image size in bytes.","example":254112},"width":{"type":"number","description":"Width in pixels."},"height":{"type":"number","description":"Height in pixels."}},"required":["url","name","size"]},"IntlBatchVideoDto":{"type":"object","properties":{"url":{"type":"string","description":"Video URL, publicly accessible."},"name":{"type":"string","description":"Video title / file name."},"size":{"type":"number","description":"Video size in **MB** (the same unit as for single video checks, not bytes).","example":12.4},"duration":{"type":"number","description":"Video duration in seconds. Billing is based on this value.","example":45},"width":{"type":"number","description":"Width in pixels."},"height":{"type":"number","description":"Height in pixels."}},"required":["url","name","size","duration"]},"CreateIntlBatchDto":{"type":"object","properties":{"name":{"type":"string","description":"Batch name, 1–60 characters.","example":"Holiday campaign · batch 1"},"platform":{"type":"string","description":"Publishing platform, applied to the whole batch.","enum":["tiktok_us","amazon_us","dtc_us","meta_ads","google_ads","tiktok_ads"],"example":"tiktok_us"},"vertical":{"type":"string","description":"Content category, applied to the whole batch.","enum":["general","beauty","health","supplement","weight_loss","baby","apparel","jewelry","home","pet"],"example":"supplement"},"texts":{"description":"Text items, up to 10. **Items shorter than 10 characters are dropped instead of failing the whole batch.** Rejecting a submission of ten items because one of them is too short, with an error message that cannot say which one, would not be a good contract.","type":"array","items":{"type":"string"}},"images":{"description":"Image items, up to 20.","type":"array","items":{"$ref":"#/components/schemas/IntlBatchImageDto"}},"videos":{"description":"Video items, up to 10.","type":"array","items":{"$ref":"#/components/schemas/IntlBatchVideoDto"}},"explainLocale":{"type":"string","description":"Language in which risk explanations are returned.","enum":["zh-CN","en-US"],"default":"zh-CN"}},"required":["name","platform","vertical"]},"IntlBatchCountsDto":{"type":"object","properties":{"texts":{"type":"number","description":"Number of text items."},"images":{"type":"number","description":"Number of image items."},"videos":{"type":"number","description":"Number of video items."}},"required":["texts","images","videos"]},"IntlBatchProgressDto":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items.","example":12},"done":{"type":"number","description":"Number of completed items.","example":9},"percent":{"type":"number","description":"Completion percentage (0–100).","example":75}},"required":["total","done","percent"]},"IntlBatchItemSummaryDto":{"type":"object","properties":{"violation":{"type":"number","description":"Number of violations."},"sceneHint":{"type":"number","description":"Number of scene hints."}},"required":["violation","sceneHint"]},"IntlBatchListItemDto":{"type":"object","properties":{"id":{"type":"string","description":"Batch ID."},"object":{"type":"string","description":"Object type.","example":"intl_batch"},"name":{"type":"string","description":"Batch name."},"status":{"type":"string","description":"Batch status."},"counts":{"description":"Number of items of each type.","allOf":[{"$ref":"#/components/schemas/IntlBatchCountsDto"}]},"progress":{"description":"Progress.","allOf":[{"$ref":"#/components/schemas/IntlBatchProgressDto"}]},"result":{"type":"object","description":"Batch verdict.","nullable":true},"summary":{"description":"Batch counts.","allOf":[{"$ref":"#/components/schemas/IntlBatchItemSummaryDto"}]},"createdAt":{"type":"object","description":"Creation time."},"finishedAt":{"type":"object","description":"Completion time.","nullable":true}},"required":["id","object","name","status","counts","progress","result","summary","createdAt","finishedAt"]},"IntlBatchListResponseDto":{"type":"object","properties":{"object":{"type":"string","description":"Object type. Always list.","example":"list"},"page":{"type":"number","description":"Current page number.","example":1},"pageSize":{"type":"number","description":"Number of items per page.","example":20},"total":{"type":"number","description":"Total number of matching items.","example":128},"hasMore":{"type":"boolean","description":"Whether there is another page.","example":true},"data":{"description":"Items on this page.","type":"array","items":{"$ref":"#/components/schemas/IntlBatchListItemDto"}}},"required":["object","page","pageSize","total","hasMore","data"]},"IntlBatchItemDto":{"type":"object","properties":{"id":{"type":"string","description":"Item ID (not the check ID)."},"kind":{"type":"string","description":"Item type. Note that the value is `text`, not the internal name script, which matches the paths of the single-item endpoints.","enum":["text","image","video"]},"checkId":{"type":"string","description":"The corresponding **single-item check ID**. Use it with `/text|image|video/checks/{id}` to get the full details."},"index":{"type":"number","description":"Index of the item in the order it was submitted.","example":0},"status":{"type":"string","description":"Item status.","enum":["processing","completed","failed"]},"riskLevel":{"type":"object","description":"Item verdict. safe/low/medium/high for text; PASS/REVIEW/REJECT for images and videos.","nullable":true},"summary":{"description":"Item counts.","allOf":[{"$ref":"#/components/schemas/IntlBatchItemSummaryDto"}]},"text":{"type":"string","description":"Text item: the original text."},"riskCount":{"type":"number","description":"Text item: number of risks."},"image":{"type":"object","description":"Image item: URL and title."},"video":{"type":"object","description":"Video item: URL, title, and duration."},"labels":{"description":"Image / video item: risk labels.","type":"array","items":{"type":"string"}},"transcriptStatus":{"type":"object","description":"Video item: voiceover transcription status.","nullable":true}},"required":["id","kind","checkId","index","status","riskLevel","summary"]},"IntlBatchResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Batch ID."},"object":{"type":"string","description":"Object type.","example":"intl_batch"},"name":{"type":"string","description":"Batch name."},"platform":{"type":"string","description":"Publishing platform.","enum":["tiktok_us","amazon_us","dtc_us","meta_ads","google_ads","tiktok_ads"]},"vertical":{"type":"string","description":"Content category.","enum":["general","beauty","health","supplement","weight_loss","baby","apparel","jewelry","home","pet"]},"status":{"type":"string","description":"Batch status.","enum":["processing","completed","failed"]},"progress":{"description":"Progress.","allOf":[{"$ref":"#/components/schemas/IntlBatchProgressDto"}]},"result":{"type":"string","description":"Batch verdict. Populated only after all items are complete.","enum":["PASS","REJECT"],"nullable":true},"summary":{"description":"Batch counts.","allOf":[{"$ref":"#/components/schemas/IntlBatchItemSummaryDto"}]},"items":{"description":"Item details.","type":"array","items":{"$ref":"#/components/schemas/IntlBatchItemDto"}},"createdAt":{"type":"object","description":"Creation time."},"finishedAt":{"type":"object","description":"Completion time.","nullable":true}},"required":["id","object","name","platform","vertical","status","progress","result","summary","items","createdAt","finishedAt"]},"IntlCustomRuleResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Rule ID."},"object":{"type":"string","description":"Object type.","example":"intl_custom_rule"},"keyword":{"type":"string","description":"The term to check for.","example":"money-back guarantee"},"matchType":{"type":"string","description":"Match type.","enum":["keyword","phrase"]},"replacement":{"type":"object","description":"Replacement. If empty, matches are flagged only.","nullable":true},"note":{"type":"object","description":"Note, visible only to you.","nullable":true},"enabled":{"type":"boolean","description":"Whether the rule is enabled."},"createdAt":{"type":"object","description":"Creation time."},"updatedAt":{"type":"object","description":"Last update time."}},"required":["id","object","keyword","matchType","replacement","note","enabled","createdAt","updatedAt"]},"IntlCustomRuleListResponseDto":{"type":"object","properties":{"object":{"type":"string","description":"Object type. Always list.","example":"list"},"data":{"description":"All rules on this site (word lists are small, so results are not paginated).","type":"array","items":{"$ref":"#/components/schemas/IntlCustomRuleResponseDto"}},"total":{"type":"number","description":"Total number of rules."}},"required":["object","data","total"]},"IntlCustomRuleQuotaDto":{"type":"object","properties":{"object":{"type":"string","description":"Object type.","example":"intl_custom_rule_quota"},"used":{"type":"number","description":"Number of terms used. **The quota is account-wide and shared across sites**; it includes terms you added on other sites.","example":12},"limit":{"type":"number","description":"Word list limit for your current plan. 0 on the Basic plan.","example":500},"isPaid":{"type":"boolean","description":"Whether this site currently has a paid subscription.","example":true}},"required":["object","used","limit","isPaid"]},"IntlCustomRuleSettingsDto":{"type":"object","properties":{"object":{"type":"string","description":"Object type.","example":"intl_custom_rule_settings"},"enabled":{"type":"boolean","description":"Account-wide master switch. When off, no custom terms are applied during checks (your data is kept)."}},"required":["object","enabled"]},"IntlToggleSettingsDto":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Tenant-level master switch. When off, no custom terms are applied during checks (your data is kept). It is independent of each rule's enabled flag. **The switch itself is not set per country site**: it answers the question \"does this account use a custom word list?\""}},"required":["enabled"]},"IntlBulkImportItemDto":{"type":"object","properties":{"keyword":{"type":"string","description":"The term to check for.","maxLength":100},"replacement":{"type":"string","description":"Replacement.","maxLength":100},"note":{"type":"string","description":"Note.","maxLength":200}},"required":["keyword"]},"IntlBulkImportDto":{"type":"object","properties":{"items":{"description":"Terms to import, up to 2000 per request. Duplicates within the request and terms already in your word list are skipped automatically (each counted separately in the response) without causing an error.","type":"array","items":{"$ref":"#/components/schemas/IntlBulkImportItemDto"}}},"required":["items"]},"IntlCustomRuleImportResultDto":{"type":"object","properties":{"object":{"type":"string","description":"Object type.","example":"intl_custom_rule_import_result"},"total":{"type":"number","description":"Total number of terms submitted in this request."},"imported":{"type":"number","description":"Number of terms actually written."},"skippedDuplicate":{"type":"number","description":"Number of terms skipped because they were duplicated within the request or already exist in your word list."},"rejectedQuota":{"type":"number","description":"Number of terms rejected because they exceeded your plan's quota."}},"required":["object","total","imported","skippedDuplicate","rejectedQuota"]},"CreateIntlCustomRuleDto":{"type":"object","properties":{"keyword":{"type":"string","description":"The term to check for. On the US site, enter English terms: the text checked is English, so Chinese terms never match.","example":"money-back guarantee","maxLength":100},"matchType":{"type":"string","description":"How the term is matched: keyword = substring match (default; a match anywhere counts), phrase = word-boundary match. **For space-delimited languages such as English, use phrase**: substring matching lets a short term hit longer words (for example, cure matches secure).","enum":["keyword","phrase"],"default":"keyword"},"replacement":{"type":"string","description":"Replacement. When set, matches include `replacement`, which you can use for an exact one-click replacement; leave it empty to flag only.","example":"30-day return policy applies","maxLength":100},"note":{"type":"string","description":"Note, visible only to you.","maxLength":200},"enabled":{"type":"boolean","description":"Whether the rule is enabled. A disabled rule is kept but not applied during checks.","default":true}},"required":["keyword"]},"UpdateIntlCustomRuleDto":{"type":"object","properties":{"keyword":{"type":"string","description":"The term to check for.","maxLength":100},"replacement":{"type":"string","description":"Replacement.","maxLength":100},"note":{"type":"string","description":"Note.","maxLength":200},"enabled":{"type":"boolean","description":"Whether the rule is enabled."}}},"IntlAccountCreditsDto":{"type":"object","properties":{"total":{"type":"number","description":"Total available credits on this site.","example":8420},"subscription":{"type":"number","description":"Credits granted by your plan."},"activity":{"type":"number","description":"Credits granted through promotions."},"booster":{"type":"number","description":"Credits from credit packs."},"expiringSoon":{"type":"object","description":"Credits that expire within 7 days; null if there are none.","nullable":true}},"required":["total","subscription","activity","booster","expiringSoon"]},"IntlAccountResponseDto":{"type":"object","properties":{"object":{"type":"string","description":"Object type.","example":"intl_account"},"country":{"type":"string","description":"The site this call belongs to.","example":"us"},"credits":{"description":"Credit balance **for this site**. Credits are isolated by site; your balance on the ByeRisk China site is not included here.","allOf":[{"$ref":"#/components/schemas/IntlAccountCreditsDto"}]},"subscription":{"type":"object","description":"Plan on this site."},"usageThisMonth":{"type":"object","description":"Number of checks of each type on this site in the current calendar month, across all entry points, including web and API."}},"required":["object","country","credits","subscription","usageThisMonth"]},"CreateIntlUploadPolicyDto":{"type":"object","properties":{"kind":{"type":"string","description":"Asset type, which determines the size limit: video up to 1GB, image up to 10MB.","enum":["video","image"]}},"required":["kind"]},"IntlUploadPolicyResponseDto":{"type":"object","properties":{"object":{"type":"string","description":"Object type.","example":"intl_upload_policy"},"kind":{"type":"string","description":"Asset type.","enum":["video","image"]},"host":{"type":"string","description":"Target URL for the direct upload (POST the form here)."},"cdnHost":{"type":"string","description":"Host from which the asset is served after a successful upload. Asset URL = `{cdnHost}/{key}`."},"dir":{"type":"string","description":"Directory prefix you are allowed to write to. key must start with it, or the upload is rejected."},"policy":{"type":"string","description":"Upload policy (base64)."},"accessKeyId":{"type":"string","description":"AccessKeyId for the direct upload."},"signature":{"type":"string","description":"Policy signature."},"maxSizeBytes":{"type":"number","description":"Size limit for this type, in bytes."},"expiresAt":{"type":"string","description":"Credential expiration time (ISO 8601). The credentials expire 5 minutes after issue."}},"required":["object","kind","host","cdnHost","dir","policy","accessKeyId","signature","maxSizeBytes","expiresAt"]}}}}