Partners who store their media and files in Wasabi can use AiR APIs to manage and retrieve their metadata, as well as create workflows. With the appropriate permissions, partners can initiate jobs, check their status, and request item metadata using a Wasabi access key and secret key for authentication.
Access to Wasabi AiR is managed through an IAM policy in the Wasabi Management Console, which can be applied either through a Group or directly to an IAM User.
Key Wasabi AiR API Capabilities
Here are some of the core functions provided by the Wasabi AiR public APIs:
Job submission — You submit a job for a given storage object (for example, a video file, image, or document) specifying which services you want to run (OCR, speech-to-text, logo detection, scene description, etc.).
Job status and monitoring — You can check the status of submitted jobs (pending, processing, completed, failed) through endpoints.
Metadata retrieval — After processing, you retrieve the resulting metadata (in JSON) that describes what was found in the media.
Listing/filtering jobs — You can list jobs (with query parameters: status, date, batch) so you can track what’s ongoing or has been processed.
Authentication and access control — The API uses access/secret keys (or policies) to secure access. You assign policies (for example, WasabiViewAiR, WasabiManageAiR).
Integration / workflow support — You hook this into event notifications (for example, when a new file is uploaded), and then persist/stitch the resulting metadata into your search/indexing/asset management systems.
Using Wasabi AiR Public APIs
Using Wasabi AiR APIs, partners can create workflows to manage and retrieve metadata.
Accessing Wasabi AiR
Users will access the Wasabi AiR capability through an IAM policy in the Wasabi console. This policy is applied either through a Group or directly to an IAM user. This capability is not available for individual ML tools, but is simplified:
{“Effect”: “Allow”, “Action”: [ “airml:*"], “Resource”: “*”}
Or
{“Effect”: “Allow”, “Action”: [“airml:Get*", “airml:list*”], “Resource”: “*”}
Permissions can be adjusted as needed, but we should begin with full access and read-only access.
Job Creation – Single Item
Users with the appropriate permissions will be able to initiate a job using the POST /jobs endpoint with the following:
S3 URI of an item
job name
Wasabi Account ID
Batch (optional)
priority (optional)
service(s) and configurations
output bucket for the completed metadata
This will initiate the processing of a single file. The API will respond with a job_id that can be used in subsequent calls to track, edit, cancel, and possibly return completed metadata for the job.
Job Definition – Single Item
Users with the appropriate permissions can recall a job definition that was submitted to the engine if they want to verify the service(s) or configurations to copy or manipulate the job. You can recall a job definition using GET /jobs/{{job_id}}.
Job Status – Single Item
Users with the appropriate permissions can track jobs using the GET /jobs/{{job_id}}/status endpoint to return the current job status. The response is:
job_id
Status (submitted, preflight, processing, completed, failed)
Job Manipulation – Single Item
Users with the appropriate permissions can manipulate jobs in certain phases. This includes updating the job definition or cancelling jobs in various stages.
To update the scope of submitted jobs only (previous jobs cannot be changed), use PUT /jobs/{{job_id}} with the entire job definition. The user cannot add additional fields but must entirely replace the job definition from the initial request.
To cancel the processing of a job, use DELETE /jobs/{{job_id}}. Jobs that are in submitted and preflight status may be cancelled without incurring cost; however, jobs in process cannot be cancelled.
Metadata Retrieval – Single Item
Retrieving metadata depends on the average expected file size and what can be managed within GAT. The ideal scenario would be to allow users with the appropriate permissions to retrieve the JSON output from the completed job using GET /jobs/{{job_id}}/metadata. Depending on the capability of GAT to maintain and return this data, a second option would be to return the output path of the metadata file for the job. Initially, plan only to return the output file path and accommodate more if possible.
Job Creation – Batch
Users with the appropriate permissions can initiate a job with the POST /jobs endpoint and include the optional batch field. The batch field should be a string that may reject certain characters that cannot be URL encoded. Although each job is triggered and run separately, the batch field defines a relationship between disparate jobs. This also protects users from unintentionally triggering large jobs that could potentially incur high costs. Users can build processes around large jobs natively in their own systems, through API programs like Postman, as well as enable the Wasabi team to build helper functions to trigger entire buckets from the console, if necessary.
Job Status – All Jobs
Users with the appropriate permissions can programmatically recall all jobs and then filter on the results. To see the status of all jobs, use the GET /jobs endpoint. A paginated response of 100 results is returned by default. The default API response can be overridden with query parameter key-value pairs. For example, to return more than 100 items per paginated response, you will include the filter GET /jobs?count=1000. Any results over the count threshold would be available by updating the call to include &page=1, etc. The filter can also be used to recall only jobs from a batch, status, or name, for example:
batch (GET /jobs?batch={{batch string}})
status (GET /jobs?batch=completed
name (GET /jobs?name={{name string}})
Public API Example
The following API example may differ from the Wasabi AiR endpoints. For current endpoints, refer to Wasabi AiR Endpoints.
swagger: '2.0'
info:
version: '1.0.0'
title: 'Air Jobs'
description: 'API for submitting jobs for processing'
host: air.wasabisys.com
basePath: /api/v1
schemes:
- https
paths:
/jobs:
post:
summary: Submit a new job
description: Submit a job with specified configuration and settings.
consumes:
- application/json
produces:
- application/json
security:
- WasabiAuth: []
- WasabiSecretAuth: []
parameters:
- name: JobSubmissionRequest
in: body
description: Job details for processing
required: true
schema:
$ref: '#/definitions/JobSubmissionRequest'
responses:
'200':
description: Job submission successful
schema:
$ref: '#/definitions/JobSubmissionResponse'
'400':
description: Invalid request (e.g., parsing errors, missing/invalid fields, source/destination issues)
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
Error: "source object not found or inaccessible"
ErrorCode: "BAD_REQUEST"
'401':
description: Unauthorized
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
Error: "Unauthorized"
ErrorCode: "UNAUTHORIZED"
"403":
description: "Monthly quota reached"
schema:
$ref: '#/definitions/ErrorResponse'
"429":
description: Daily Cap Exceeded
schema:
$ref: '#/definitions/ErrorResponse'
'500':
description: Internal Server Error
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
Error: "An unexpected error occurred while processing the job."
ErrorCode: "INTERNAL_ERROR"
get:
summary: Get a list of jobs
description: Retrieves a paginated list of jobs, optionally filtered by criteria such as batch, name, or status, and sorted by created or completed date.
produces:
- application/json
security:
- WasabiAuth: []
- WasabiSecretAuth: []
parameters:
- name: pageNumber
in: query
required: false
type: integer
minimum: 1
description: The page number to retrieve (default is 1).
- name: pageSize
in: query
required: false
type: integer
minimum: 1
maximum: 100
default: 100
description: The number of jobs to return per page (default is 25).
- name: batch
in: query
required: false
type: string
description: Filters jobs by the batch identifier.
- name: status
in: query
required: false
type: string
enum:
- submitted
- preflight
- in_progress
- completed
- failed
- cancelled
description: Filters jobs by status.
- name: name
in: query
required: false
type: string
description: Filters jobs by the name identifier.
- name: sortBy
in: query
required: false
type: string
enum:
- Created
description: Sorts the results by the specified field.
- name: sortOrder
in: query
required: false
type: string
enum:
- Asc
- Desc
description: "Specifies the sort direction: ascending (`Asc`) or descending (`Desc`). Default is `Asc`."
responses:
'200':
description: Job details retrieved successfully
schema:
type: object
properties:
Records:
type: array
items:
$ref: '#/definitions/JobList'
Pagination:
type: object
properties:
TotalRecords:
type: integer
minimum: 0
description: Total number of jobs available.
PageNumber:
type: integer
description: Current page number.
PageSize:
type: integer
description: Number of jobs per page.
'400':
description: Invalid request (e.g., parsing errors, missing/invalid fields, source/destination issues)
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
Error: "The limit on the number of rows allowed to query is %d! Please adjust pageNumber and/or pageSize."
ErrorCode: "BAD_REQUEST"
'401':
description: Unauthorized
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
Error: "Unauthorized"
ErrorCode: "UNAUTHORIZED"
'500':
description: Internal Server Error
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
Error: "An unexpected error occurred while processing the job."
ErrorCode: "INTERNAL_ERROR"
/jobs/{Id}:
get:
summary: Get job details
description: Retrieves details of the specified job, including the original job definition.
produces:
- application/json
security:
- WasabiAuth: []
- WasabiSecretAuth: []
parameters:
- name: Id
in: path
required: true
type: string
description: The ID of the job to retrieve.
responses:
'200':
description: Job details retrieved successfully
schema:
$ref: '#/definitions/Job'
'401':
description: Unauthorized
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
Error: "Unauthorized"
ErrorCode: "UNAUTHORIZED"
'404':
description: Job not found
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
ErrorCode: "NOT_FOUND"
'500':
description: Internal Server Error
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
Error: "An unexpected error occurred while processing the job."
ErrorCode: "INTERNAL_ERROR"
/jobs/{Id}/status:
get:
summary: Get job status
description: Fetches the current status of a job.
produces:
- application/json
security:
- WasabiAuth: []
- WasabiSecretAuth: []
parameters:
- name: Id
in: path
required: true
type: string
responses:
'200':
description: Job status retrieved successfully
schema:
$ref: '#/definitions/JobStatus'
'401':
description: Unauthorized
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
Error: "Unauthorized"
ErrorCode: "UNAUTHORIZED"
'404':
description: Job not found
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
ErrorCode: "NOT_FOUND"
'500':
description: Internal Server Error
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
Error: "An unexpected error occurred while processing the job."
ErrorCode: "INTERNAL_ERROR"
/jobs/{Id}/errors:
get:
summary: Get job error
description: Fetches the error of a job.
produces:
- application/json
security:
- WasabiAuth: []
- WasabiSecretAuth: []
parameters:
- name: Id
in: path
required: true
type: string
responses:
'200':
description: Job error retrieved successfully
schema:
$ref: '#/definitions/JobErrors'
'401':
description: Unauthorized
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
Error: "Unauthorized"
ErrorCode: "UNAUTHORIZED"
'404':
description: Job not found
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
ErrorCode: "NOT_FOUND"
'500':
description: Internal Server Error
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
Error: "An unexpected error occurred while processing the job."
ErrorCode: "INTERNAL_ERROR"
/jobs/{Id}/metadata:
get:
summary: Get job metadata
description: Retrieves metadata of a completed job.
produces:
- application/json
security:
- WasabiAuth: []
- WasabiSecretAuth: []
parameters:
- name: Id
in: path
required: true
type: string
description: The ID of the job.
responses:
'200':
description: Job metadata retrieved successfully
schema:
$ref: '#/definitions/MetaResponse'
'401':
description: Unauthorized
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
Error: "Unauthorized"
ErrorCode: "UNAUTHORIZED"
'404':
description: Job not found
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
ErrorCode: "NOT_FOUND"
'500':
description: Internal Server Error
schema:
$ref: '#/definitions/ErrorResponse'
examples:
application/json:
Error: "An unexpected error occurred while processing the job."
ErrorCode: "INTERNAL_ERROR"
securityDefinitions:
WasabiAuth:
type: apiKey
in: header
name: x-amz-access-key
description: "Wasabi access key for authenticating requests. A valid Wasabi User access key is required for API calls."
WasabiSecretAuth:
type: apiKey
in: header
name: x-amz-secret-key
description: "Wasabi secret key for authenticating requests. A valid Wasabi User secret key is required along with the access key."
parameters:
ParamMinHealth:
in: query
name: MinHealth
type: integer
format: uint32
minimum: 0
default: 25
maximum: 1000
required: false
description: Minimum acceptable health percentage for readiness check
definitions:
JobList:
type: object
properties:
Id:
type: string
description: Unique ID for the job
example: "67345137bcb6dce44b35a6a6281711e7"
Name:
type: string
description: Name of the job
example: "MyJobName"
Source:
type: object
properties:
Endpoint:
type: string
description: "S3 endpoint URL"
example: "s3.us-west-1.wasabisys.com"
Bucket:
type: string
description: "Source bucket name"
example: "wasabifs-chm"
Region:
type: string
description: "S3 region"
example: "us-west-1"
ObjectKey:
type: string
description: "Object key or path to the file"
example: "MP4/Commercial.mp4"
Provider:
type: string
description: "Storage provider, e.g., wasabi, OBS, IBM"
UserId:
type: string
description: User who submitted the job (e.g., an ARN)
example: "10000"
Created:
type: string
format: date-time
description: Timestamp when the job was created
example: "2024-11-13T07:11:51.65847Z"
Completed:
type: string
format: date-time
description: Timestamp when the job was completed
example: "2024-11-13T07:11:51.65847Z"
x-nullable: true
Priority:
description: |-
Job priority (1-10).
example: 5
type: integer
Batch:
type: string
description: Optional batch identifier for grouping jobs
example: "batch_2024_11_21"
Status:
type: string
description: Current status of the job
enum:
- submitted
- preflight
- in_progress
- completed
- failed
- cancelled
example: "submitted"
Destination:
type: object
properties:
Bucket:
type: string
description: "Destination bucket name"
example: "airstream-output-2"
Region:
type: string
description: "S3 region"
example: "us-west-1"
Job:
type: object
properties:
Id:
type: string
description: Unique ID for the job
example: "67345137bcb6dce44b35a6a6281711e7"
Name:
type: string
description: Name of the job
example: "MyJobName"
Source:
type: object
properties:
Endpoint:
type: string
description: "S3 endpoint URL"
example: "s3.us-west-1.wasabisys.com"
Bucket:
type: string
description: "Source bucket name"
example: "wasabifs-chm"
Region:
type: string
description: "S3 region"
example: "us-west-1"
ObjectKey:
type: string
description: "Object key or path to the file"
example: "MP4/Commercial.mp4"
Provider:
type: string
description: "Storage provider, e.g., wasabi, OBS, IBM"
Services:
type: object
description: Services and their configurations
example: |
{
"ocr": "",
"s2t": "",
"nld": "",
"audiotag": "",
"face": "",
"logo": {
"config": {
"rec_confidence_threshold": 0.85
}
}
}
UserId:
type: string
description: User who submitted the job (e.g., an ARN)
example: "10000"
Created:
type: string
format: date-time
description: Timestamp when the job was created
example: "2024-11-13T07:11:51.65847Z"
Completed:
type: string
format: date-time
description: Timestamp when the job was completed
example: "2024-11-13T07:11:51.65847Z"
x-nullable: true
Priority:
description: |-
Job priority (1-10).
example: 5
type: integer
Batch:
type: string
description: Optional batch identifier for grouping jobs
example: "batch_2024_11_21"
Status:
type: string
description: Current status of the job
enum:
- submitted
- preflight
- in_progress
- completed
- failed
- cancelled
example: "submitted"
Destination:
type: object
properties:
Bucket:
type: string
description: "Destination bucket name"
example: "airstream-output-2"
Region:
type: string
description: "S3 region"
example: "us-west-1"
JobSubmissionRequest:
type: object
required:
- Source
- Destination
- Services
- Name
properties:
Name:
type: string
description: Name of the job
example: "MyJobName"
maxLength: 256
minLength: 1
pattern: '^.*\S.*$'
Priority:
type: integer
description: Job priority (1-10)
minimum: 1
maximum: 10
example: 5
Services:
type: object
description: |
Required. Select which services to execute and optionally provide per‑service configuration. Fewer than 1 service will be rejected.
- Provide a JSON object where each key is a service identifier (e.g., "ocr", "s2t", "nld", "audiotag", "face", "logo").
- Include a key to enable that service.
- For each service value:
- use {} to accept defaults, or
- provide an object with "config" to override service‑specific parameters (e.g., confidence thresholds).
example: |
{
"ocr": "",
"s2t": "",
"nld": "",
"audiotag": "",
"face": "",
"logo": {
"config": {
"rec_confidence_threshold": 0.85
}
}
}
Batch:
type: string
description: Optional batch identifier for grouping jobs
example: "batch_2024_11_21"
maxLength: 256
Destination:
type: object
required:
- Region
- Bucket
properties:
Bucket:
type: string
description: "Destination bucket name"
example: "airstream-output-2"
Region:
type: string
description: "S3 region"
example: "us-west-1"
Source:
type: object
properties:
Endpoint:
type: string
description: "S3 endpoint URL"
example: "s3.us-west-1.wasabisys.com"
Bucket:
type: string
description: "Source bucket name"
example: "wasabifs-chm"
Region:
type: string
description: "S3 region"
example: "us-west-1"
ObjectKey:
type: string
description: "Object key or path to the file"
example: "MP4/Commercial.mp4"
required:
- Bucket
- ObjectKey
JobSubmissionResponse:
type: object
properties:
Job:
$ref: '#/definitions/Job'
JobStatus:
type: object
properties:
Id:
type: string
example: "12345"
Status:
type: string
description: Current status of the job
enum:
- submitted
- preflight
- in_progress
- completed
- failed
- cancelled
example: "in_progress"
ErrorCount:
type: integer
description: Count of errors encountered
example: 0
default: 0
JobErrors:
type: object
required:
- Id
- Status
- ErrorCount
properties:
Id:
type: string
example: "12345"
Status:
type: string
description: Current status of the job
enum:
- submitted
- preflight
- in_progress
- completed
- failed
- cancelled
example: "in_progress"
ErrorCode:
type: string
description: Error code for troubleshooting
example: "INTERNAL_ERROR"
ErrorCount:
type: integer
description: Error count
example: "0"
default: 0
ErrorResponse:
type: object
properties:
Error:
type: string
description: Error message explaining what went wrong
example: "An unexpected error occurred while processing the job."
ErrorCode:
type: string
description: Error code for troubleshooting
example: "INTERNAL_ERROR"
MetaResponse:
type: object
properties:
Id:
type: string
example: "12345"
UserId:
type: string
description: User who submitted the job (e.g., an ARN)
example: "1000"
Destination:
type: object
properties:
Bucket:
type: string
description: "Destination bucket name"
example: "airstream-output-2"
Region:
type: string
description: "S3 region"
example: "us-west-1"
DestinationPath:
type: string
description: "Metadata file"
example: "s3://metabucket/jobs/2025_04_29/7b6ba1dd-b4a2-42d2-8825-0f41c2355c4d/philtest_metadata.json"Wasabi AiR API Endpoints
POST /jobs — Submits a job with specified configuration and settings.
GET /jobs/{jobId}/status — Fetches the current status of a job.
GET /jobs/{jobId} — Fetches job details, including configuration.
GET /jobs/{jobId}/metadata — Retrieves the metadata output of a completed job.
GET /jobs — Lists jobs with optional filters like status or date.
GET /jobs/{Id}/errors — Fetches the error of a job.