openapi: 3.0.1
info:
title: MNTN Async Batch Export API - Batch
description: '## Overview
Submit long-running **CSV** exports of reporting queries, poll **status**, then download results via
**time-limited signed URLs**. Endpoints are under **`/batch`…** (requires `r2ds.exports.enabled`).
## Lifecycle
1. **`POST /batch`** — enqueue a job; response includes `batchId` and initial status (**202 Accepted**).
2. **`GET /batch/{batchId}`** — status; when `SUCCEEDED`, a fresh **download URL** may be included.
3. **`POST /batch/{batchId}/regenerate-url`** — issue a new signed URL without re-running the query.
4. **`GET /batch`** — list recent jobs (optional `status`, `limit`, `offset` query params).
'
version: 3.7.0
servers:
- url: https://api3.mountain.com
description: MNTN Reporting API 3.0
tags:
- name: Batch
description: Async CSV exports under **`/batch`…** (submit, poll status, signed download URLs)
paths:
/batch:
get:
tags:
- Batch
summary: List export jobs
description: 'Returns a page of batch jobs for the authenticated advertiser. Optional `status` filters to comma-separated
values: QUEUED, PROCESSING, SUCCEEDED, FAILED.'
operationId: listExports
parameters:
- name: status
in: query
description: Comma-separated status filter (QUEUED, PROCESSING, SUCCEEDED, FAILED)
required: false
schema:
type: string
- name: key
in: query
description: API key
required: true
schema:
type: string
- name: limit
in: query
description: Page size
required: false
schema:
type: integer
format: int32
default: 20
- name: offset
in: query
description: Page offset
required: false
schema:
type: integer
format: int32
default: 0
responses:
'500':
description: Internal Server Error
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'401':
description: Unauthorized
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'400':
description: Invalid query parameters (for example malformed `status`)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'504':
description: Gateway Timeout — the query exceeded the synchronous request time limit.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'404':
description: Not Found
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'413':
description: Payload Too Large — the query exceeds server memory limits. Use the asynchronous /batch endpoint for
large requests.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'200':
description: Paged list of exports
content:
application/json:
schema:
$ref: '#/components/schemas/ExportListResponse'
post:
tags:
- Batch
summary: Submit an async export job
description: Queues a CSV export for the authenticated advertiser. Returns **202 Accepted** with a `batchId` and initial
status; poll `GET /batch/{batchId}` until `SUCCEEDED`, then use the signed `downloadUrl`.
operationId: submitExport
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ExportRequest'
required: true
responses:
'500':
description: Unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'400':
description: Validation or invalid request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'504':
description: Gateway Timeout — the query exceeded the synchronous request time limit.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'404':
description: Not Found
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'413':
description: Payload Too Large — the query exceeds server memory limits. Use the asynchronous /batch endpoint for
large requests.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'202':
description: Job accepted
content:
application/json:
schema:
$ref: '#/components/schemas/ExportResponse'
'429':
description: Rate limit exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/ExportResponse'
/batch/{batchId}/regenerate-url:
post:
tags:
- Batch
summary: Issue a freshly-signed download URL for a SUCCEEDED batch
description: Returns a new signed URL for the result file without re-executing the query. Effect is equivalent to re-calling
GET /batch/{batchId}, but the response carries only the URL fields — no other batch metadata.
operationId: regenerateUrl
parameters:
- name: batchId
in: path
description: Batch job identifier.
required: true
schema:
type: integer
format: int64
- name: key
in: query
description: Advertiser API key.
required: true
schema:
type: string
responses:
'500':
description: Internal Server Error
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'401':
description: Unauthorized
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'400':
description: Batch is queued or processing
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'504':
description: Gateway Timeout — the query exceeded the synchronous request time limit.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'404':
description: Batch not found
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'413':
description: Payload Too Large — the query exceeds server memory limits. Use the asynchronous /batch endpoint for
large requests.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'409':
description: Batch is in a terminal non-downloadable state
content:
application/json:
schema:
$ref: '#/components/schemas/RegenerateUrlResponse'
'200':
description: Fresh signed URL issued
content:
application/json:
schema:
$ref: '#/components/schemas/RegenerateUrlResponse'
'410':
description: Result is permanently unavailable
content:
application/json:
schema:
$ref: '#/components/schemas/RegenerateUrlResponse'
'503':
description: Signing subsystem temporarily unavailable
content:
application/json:
schema:
$ref: '#/components/schemas/RegenerateUrlResponse'
/batch/{batchId}:
get:
tags:
- Batch
summary: Get batch status (includes signed download URL when eligible)
description: Returns the batch status. When the batch is SUCCEEDED and within retention, a freshly-signed download URL
is included in the response. The URL is generated on every call — clients should not treat it as stable.
operationId: getExportStatus
parameters:
- name: batchId
in: path
description: Batch job identifier returned from **POST /batch**.
required: true
schema:
type: integer
format: int64
- name: key
in: query
description: Advertiser API key (same as **GET /batch** list).
required: true
schema:
type: string
responses:
'500':
description: Internal Server Error
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'401':
description: Unauthorized
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'400':
description: Bad Request
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'504':
description: Gateway Timeout — the query exceeded the synchronous request time limit.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'404':
description: Batch not found
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'413':
description: Payload Too Large — the query exceeds server memory limits. Use the asynchronous /batch endpoint for
large requests.
content:
application/problem+json:
schema:
$ref: '#/components/schemas/ProblemDetail'
'503':
description: Signing subsystem temporarily unavailable
content:
application/json:
schema:
$ref: '#/components/schemas/ExportStatusResponse'
'200':
description: Batch status
content:
application/json:
schema:
$ref: '#/components/schemas/ExportStatusResponse'
security:
- API Key: []
components:
schemas:
SimpleColumn:
type: object
allOf:
- $ref: '#/components/schemas/DataColumn'
Or:
type: object
allOf:
- $ref: '#/components/schemas/Filter'
DataColumn:
required:
- type
type: object
properties:
alias:
type: string
friendly:
type: string
name:
type: string
type:
type: string
description: List of data columns to query
discriminator:
propertyName: type
ExportListResponse:
type: object
properties:
batches:
type: array
items:
$ref: '#/components/schemas/ExportStatusResponse'
total:
type: integer
format: int32
limit:
type: integer
format: int32
offset:
type: integer
format: int32
ExportRequest:
title: Batch Request
required:
- begin
- data
- key
type: object
properties:
key:
type: string
description: API Key
data:
type: array
description: List of data columns to query
items:
oneOf:
- $ref: '#/components/schemas/FilteredColumn'
- $ref: '#/components/schemas/SimpleColumn'
begin:
type: string
description: Start date (YYYY-MM-DD) or keyword
end:
type: string
description: End date (YYYY-MM-DD); required when begin is an explicit date and ignored for keyword begin
format:
type: string
description: Output format
enum:
- csv
default: csv
fullname:
type: boolean
description: Include table prefix in column names
default: false
includetoday:
type: boolean
description: Include current day's partial data
default: false
limit:
type: integer
description: Max rows returned; defaults to the configured export maximum when omitted
format: int32
offset:
type: integer
description: Row offset for pagination
format: int32
default: 0
sort:
type: array
description: Sort order (column direction)
items:
type: string
description: Sort order (column direction)
sum:
type: array
description: Group-by columns
items:
type: string
description: Group-by columns
reportName:
type: string
description: Optional report name for identification
filter:
$ref: '#/components/schemas/Filter'
allownull:
type: boolean
formatdata:
type: boolean
nodatatiercheck:
type: string
period:
type: string
dataColumns:
type: array
items:
type: string
description: Batch Request
ExportStatusResponse:
type: object
properties:
batchId:
type: integer
format: int64
status:
type: string
submittedAt:
type: string
reportName:
type: string
requestParams:
type: string
startedAt:
type: string
completedAt:
type: string
downloadUrl:
type: string
downloadExpiresAt:
type: string
error:
$ref: '#/components/schemas/ExportErrorDetail'
And:
type: object
allOf:
- $ref: '#/components/schemas/Filter'
ProblemDetail:
title: Problem Detail (RFC 9457)
type: object
properties:
type:
type: string
description: A URI reference that identifies the problem type
example: https://api3.mntn.com/problems/query-timeout
title:
type: string
description: A short, human-readable summary of the problem type (stable across occurrences)
example: Gateway Timeout
status:
type: integer
description: The HTTP status code
format: int32
example: 504
detail:
type: string
description: A human-readable explanation specific to this occurrence of the problem
example: Gateway Timeout
instance:
type: string
description: A URI reference that identifies the specific occurrence of the problem (request path)
example: /data?aid=12345
timestamp:
type: string
description: ISO 8601 timestamp when the error occurred
example: '2026-01-08T17:21:59.445461Z'
errorCode:
type: string
description: Internal error code for support reference
example: QUERY_TIMEOUT
traceId:
type: string
description: OpenTelemetry trace ID for debugging and support
example: 64a8b3c2d1e0f9876543210abcdef123
errors:
type: array
description: Array of validation errors (for 400 Bad Request responses)
items:
type: object
properties:
field:
type: string
description: Field name that failed validation
example: aid
message:
type: string
description: Error message
example: Advertiser ID is required
description: 'Standard error response format following RFC 9457 (Problem Details for HTTP APIs).
All error responses include machine-readable problem types and human-readable details.
See: https://www.rfc-editor.org/rfc/rfc9457.html'
example: '{Invalid API Key (401)={type=https://api3.mntn.com/problems/authorization-error, title=Invalid API Key, status=401,
detail=The provided API key ''abc123...'' is not valid, instance=/apidata, timestamp=2026-01-08T17:21:59.445461Z,
errorCode=INVALID_API_KEY, traceId=64a8b3c2d1e0f9876543210abcdef123}, Validation Error (400)={type=https://api3.mntn.com/problems/general-request-error,
title=Bad Request, status=400, detail=Request validation failed, instance=/apidata, timestamp=2026-01-08T17:21:59.445461Z,
errorCode=GENERAL_REQUEST_ERROR, errors=[{field=aid, message=Advertiser ID is required}, {field=begin, message=Start
date is required}]}, Metadata Error (400)={type=https://api3.mntn.com/problems/metadata-error, title=Metadata Error,
status=400, detail=Table ''Inventory1'' does not exist, instance=/apidata?aid=12345, timestamp=2026-01-08T17:21:59.445461Z,
errorCode=METADATA_ERROR, traceId=64a8b3c2d1e0f9876543210abcdef123}, Query Timeout (504)={type=https://api3.mntn.com/problems/query-timeout,
title=Gateway Timeout, status=504, detail=Gateway Timeout, instance=/apidata?aid=12345&begin=2020-01-01&end=2025-12-31,
timestamp=2026-01-08T17:21:59.445461Z, traceId=64a8b3c2d1e0f9876543210abcdef123}, Resource Limit Exceeded (400)={type=https://api3.mntn.com/problems/resource-limit-exceeded,
title=Resource Limit Exceeded, status=400, detail=Query returned too many rows. Please narrow your date range or refine
`filter`., instance=/data?aid=12345&begin=2020-01-01&end=2025-12-31, timestamp=2026-01-08T17:21:59.445461Z, errorCode=RESOURCE_LIMIT_EXCEEDED,
traceId=64a8b3c2d1e0f9876543210abcdef123}, Internal Server Error (500)={type=https://api3.mntn.com/problems/internal-error,
title=Internal Server Error, status=500, detail=An unexpected error occurred while processing the request, instance=/apidata,
timestamp=2026-01-08T17:21:59.445461Z, errorCode=NA, traceId=64a8b3c2d1e0f9876543210abcdef123}}'
Not:
type: object
allOf:
- $ref: '#/components/schemas/Filter'
ErrorResponse:
description: HTTP error / validation payload (RFC 9457); same schema as ProblemDetail
allOf:
- $ref: '#/components/schemas/ProblemDetail'
FilteredColumn:
type: object
allOf:
- $ref: '#/components/schemas/DataColumn'
- type: object
properties:
filter:
type: array
items:
oneOf:
- $ref: '#/components/schemas/And'
- $ref: '#/components/schemas/Not'
- $ref: '#/components/schemas/Or'
- $ref: '#/components/schemas/Value'
nullReplacement:
type: object
RegenerateUrlResponse:
type: object
properties:
downloadUrl:
type: string
downloadExpiresAt:
type: string
Filter:
title: Filter
type: object
additionalProperties: true
description: 'Optional JSON **object** that restricts which rows are returned. Use the same shape for **POST** `filter`
and **GET** `filter` (URL-encoded).
**Filter types — column predicates:** Each property key is a column identifier (`table.column`). The value can be:
- **Operator object:** keys are operator names and values are comparison values (for example `{"equals": "Live"}`,
`{"in": ["a","b"]}`).
- **Scalar** (string or number): shorthand for `equals`.
- **Array:** shorthand for membership (`in`).
**Filter types — logical groups:** Properties named `AND`, `OR`, or `NOT` hold a nested object that follows the same
rules (more column predicates and/or nested `AND` / `OR` / `NOT`).
**Operator keys** (allowed keys inside an operator object): `equals`, `not`, `in`, `notIn`, `lt`, `lte`, `gt`, `gte`,
`contains`, `notContains`, `startsWith`, `endsWith`, `hasAny`.
Use **GET /apilist** to discover valid column identifiers (for `data`, `sum`, and `filter`).'
example: '{"campaigninfo.id":{"in":["28915"]},"OR":{"campaigninfo.status":{"equals":"Live"},"graph.impressions":{"gte":1000}}}'
Value:
type: object
allOf:
- $ref: '#/components/schemas/Filter'
- type: object
properties:
field:
type: string
operator:
type: string
enum:
- EQUALS
- NOT
- IN
- NOT_IN
- LT
- LTE
- GT
- GTE
- CONTAINS
- NOT_CONTAINS
- STARTS_WITH
- ENDS_WITH
- HAS_ANY
value:
type: object
ExportResponse:
type: object
properties:
batchId:
type: integer
format: int64
status:
type: string
submittedAt:
type: string
reportName:
type: string
ExportErrorDetail:
type: object
properties:
code:
type: string
message:
type: string
retryable:
type: boolean
securitySchemes:
API Key:
type: apiKey
description: MNTN-issued advertiser API key. Available in Account Settings.
name: key
in: query