openapi: 3.1.0
info:
title: Air Documents API
version: v2
description: APIs to perform search, checkout and book an air pnr
servers:
- url: https://api-ext-sboxmeta.partners.spotnana.com
description: Sandbox URL
security:
- Bearer: []
tags:
- name: Documents
paths:
/v2/documents:
post:
tags:
- Documents
summary: Upload a document
description: Upload a document for a specific entity type (e.g., a PNR).
operationId: uploadDocument
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/UploadDocumentRequest'
encoding:
file:
contentType: application/pdf
documentMetadata:
contentType: application/json
documentMetadataStr:
contentType: application/json
x-codeSamples:
- lang: curl
source: "curl --location 'https://api-ext-sboxmeta.partners.spotnana.com/v2/documents' \\\n --header 'Authorization: Bearer <YOUR_TOKEN_HERE>' \\\n --header 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36' \\\n --form 'file=@\"/Path/to/file/document.pdf\"' \\\n --form 'documentMetadata=\"{\n \\\"documentType\\\": \\\"INVOICE\\\",\n \\\"entityType\\\": \\\"PNR\\\",\n \\\"entityId\\\": \\\"1234567890\\\",\n \\\"entityMetadata\\\": {\n \\\"travelType\\\": \\\"AIR\\\",\n \\\"invoiceMetadata\\\": {\n \\\"invoiceNumber\\\": \\\"ABCD-1234\\\"\n }\n },\n \\\"name\\\": \\\"Trip-Invoice-Test\\\"\n }\";type=application/json'\n"
- lang: Node.js
source: "import fetch from 'node-fetch';\nimport FormData from 'form-data';\nimport fs from 'fs';\n\n// Create the multipart form\nconst form = new FormData();\n\n// File part\nform.append(\n 'file',\n fs.createReadStream('/Path/to/file/document.pdf'),\n {\n filename: 'document.pdf',\n contentType: 'application/pdf'\n }\n);\n\n// Metadata part (JSON)\nform.append(\n 'documentMetadata',\n JSON.stringify({\n documentType: \"INVOICE\",\n entityType: \"PNR\",\n entityId: \"1234567890\",\n entityMetadata: {\n travelType: \"AIR\",\n invoiceMetadata: {\n invoiceNumber: \"ABCD-1234\"\n }\n },\n name: \"Trip-Invoice-Test\"\n }),\n {\n contentType: 'application/json'\n }\n);\n\n// Send the request\nconst response = await fetch('https://api.spotnana.com/v2/documents', {\n method: 'POST',\n headers: {\n Authorization: 'Bearer auth-token',\n ...form.getHeaders() // IMPORTANT: includes multipart boundary\n },\n body: form\n});\n\nconst result = await response.text();\nconsole.log(result);\n"
- lang: JavaScript
source: "import fs from \"fs\";\nimport path from \"path\";\n\nasync function uploadDocument() {\n const filePath = \"/Path/to/file/document.pdf\";\n\n // Read file as a buffer\n const fileBuffer = fs.readFileSync(filePath);\n\n // Create FormData\n const formData = new FormData();\n\n // Add file using Blob (Node 18+)\n formData.append(\n \"file\",\n new Blob([fileBuffer], { type: \"application/pdf\" }),\n \"document.pdf\"\n );\n\n // Metadata object\n const metadata = {\n documentType: \"INVOICE\",\n entityType: \"PNR\",\n entityId: \"1234567890\",\n entityMetadata: {\n travelType: \"AIR\",\n invoiceMetadata: {\n invoiceNumber: \"ABCD-1234\"\n }\n },\n name: \"Trip-Invoice-Test\"\n };\n\n // Add metadata JSON string\n formData.append(\"documentMetadata\", JSON.stringify(metadata));\n\n // Make request using native fetch\n const response = await fetch(\n \"https://api-ext-sboxmeta.partners.spotnana.com/v2/documents\",\n {\n method: \"POST\",\n headers: {\n Authorization: \"Bearer <YOUR_TOKEN_HERE>\"\n // Don't set Content-Type — fetch will add the multipart boundary automatically\n },\n body: formData\n }\n );\n\n const result = await response.text();\n console.log(result);\n}\n\nuploadDocument().catch(console.error);\n"
- lang: Python
source: "import requests\n\nurl = \"https://api-ext-sboxmeta.partners.spotnana.com/v2/documents\"\n\npayload = {\n 'documentMetadata': '''{\n \"documentType\": \"INVOICE\",\n \"entityType\": \"PNR\",\n \"entityId\": \"1234567890\",\n \"entityMetadata\": {\n \"travelType\": \"AIR\",\n \"invoiceMetadata\": {\n \"invoiceNumber\": \"ABCD-1234\"\n }\n },\n \"name\": \"Trip-Invoice-Test\"\n }'''\n}\n\nfiles = [\n (\n 'file',\n (\n 'document.pdf',\n open('/Path/to/file/document.pdf', 'rb'),\n 'application/pdf'\n )\n )\n]\n\nheaders = {\n 'Authorization': 'Bearer <YOUR_TOKEN_HERE>'\n}\n\nresponse = requests.request(\n \"POST\",\n url,\n headers=headers,\n data=payload,\n files=files\n)\n\nprint(response.text)\n"
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/UploadDocumentResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
get:
tags:
- Documents
summary: List documents
description: List all the uploaded documents for a specific entity ID and type.
operationId: listDocuments
parameters:
- name: entityType
in: query
description: Entity type against which document is associated.
required: true
schema:
$ref: '#/components/schemas/EntityType'
- name: entityId
in: query
description: Entity Id for the given entity type.
required: true
schema:
type: string
example: '123124'
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/GetDocumentsResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/v2/documents/{documentId}:
get:
tags:
- Documents
summary: Get document
description: Retrieve a document.
operationId: getDocument
parameters:
- name: documentId
in: path
description: Document Id
required: true
schema:
type: string
format: uuid
example: f49d00fe-1eda-4304-ba79-a980f565281d
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/GetDocumentResponse'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
delete:
tags:
- Documents
summary: Delete document
description: Delete a document.
operationId: deleteDocument
parameters:
- name: documentId
in: path
description: Document Id
required: true
schema:
type: string
format: uuid
example: f49d00fe-1eda-4304-ba79-a980f565281d
responses:
'200':
description: OK
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
components:
schemas:
Document:
type: object
title: Document
description: Document details.
required:
- url
- documentId
- documentMetadata
properties:
url:
type: string
description: S3 location of the document.
example: https://s3.amazonaws.com/bucket-name/folder-name/file-name
documentId:
type: string
format: uuid
description: Unique identifier of the document.
example: f49d00fe-1eda-4304-ba79-a980f565281d
documentMetadata:
$ref: '#/components/schemas/DocumentMetadata'
EntityMetadata:
title: EntityMetadata
description: Metadata for associated entity of document.
type: object
oneOf:
- $ref: '#/components/schemas/PnrMetadataWrapper'
- $ref: '#/components/schemas/EventMetadataWrapper'
DocumentType:
title: DocumentType
description: Document type.
type: string
enum:
- BOARDING_PASS
- CONFIRMATION
- INVOICE
- VISA
- MISCELLANEOUS
- OTHERS
- TASK_PROCESSOR
- EVENT_COVER_IMAGE
- LOGO_IMAGE
example: VISA
x-ignoreBreakingChanges:
- DocumentType->LOGO_IMAGE
PnrMetadata:
title: PnrMetadata
description: Metadata when document is associated to pnr entity.
type: object
oneOf:
- $ref: '#/components/schemas/FlightMetadataWrapper'
- $ref: '#/components/schemas/LegMetadataWrapper'
TravelType:
type: string
title: TravelType
description: Travel Type
enum:
- AIR
- HOTEL
- CAR
- RAIL
- LIMO
- MISC
- ALL
example: AIR
EntityType:
title: EntityType
description: Entity type against which the document is to uploaded.
type: string
enum:
- PNR
- COMPANY
- AIR_ITINERARY
- EVENT
- LOCATION_IMAGE
- AIR_COMMISSION_CONTRACT
example: PNR
x-ignoreBreakingChanges:
- EntityType->TRIP
- EntityType->TICKETING_ERROR
EventMetadataWrapper:
type: object
title: EventMetadataWrapper
properties:
eventMetadata:
$ref: '#/components/schemas/EventEntityMetadata'
Latlng:
title: Latlng
description: Latitude and Longitude for a Location
type: object
required:
- latitude
- longitude
properties:
latitude:
type: number
description: Latitude of the Location
format: double
example: 77.1025
longitude:
type: number
description: Longitude of the Location
format: double
example: 28.7041
GetDocumentResponse:
type: object
title: GetDocumentResponse
description: Response containing a document.
required:
- document
properties:
document:
$ref: '#/components/schemas/Document'
FlightMetadataWrapper:
type: object
title: FlightMetadataWrapper
properties:
flightMetadata:
$ref: '#/components/schemas/FlightMetadata'
PnrMetadataWrapper:
type: object
title: PnrMetadataWrapper
required:
- travelType
properties:
pnrMetadata:
$ref: '#/components/schemas/PnrMetadata'
invoiceMetadata:
type: object
title: InvoiceMetadata
description: Metadata associated with an invoice document.
required:
- invoiceNumber
properties:
invoiceNumber:
type: string
example: SPOT-0001
invoiceType:
type: string
example: FARE_INVOICE
enum:
- SERVICE_FEE_INVOICE
- FARE_INVOICE
- GENERIC_INVOICE
travelType:
$ref: '#/components/schemas/TravelType'
ErrorResponse:
type: object
properties:
debugIdentifier:
type: string
description: Link to debug the error internally.
errorMessages:
type: array
items:
type: object
properties:
errorCode:
type: string
description: Error code to identify the specific errors.
message:
type: string
description: Message containing details of error.
errorParameters:
type: array
description: Error message parameters.
items:
$ref: '#/components/schemas/ErrorParameter'
errorDetail:
type: string
description: More details about the error.
UploadDocumentRequest:
type: object
title: UploadDocumentRequest
description: Request body for upload document.
required:
- file
x-ignoreBreakingChanges:
- DocumentApi.yaml->UploadDocumentRequest->documentMetadata
- UploadDocumentRequest->documentMetadata
properties:
documentMetadata:
$ref: '#/components/schemas/DocumentMetadata'
x-optionalFrom: '2026-01-14'
file:
type: string
format: binary
description: Contents of the document to be uploaded (PDF only). Accepts application/pdf or application/octet-stream.
documentMetadataStr:
type: string
description: JSON string of DocumentMetadata - accepts application/octet-stream. Either documentMetadata or documentMetadataStr must be present.
LegMetadataWrapper:
type: object
title: LegMetadataWrapper
properties:
legMetadata:
$ref: '#/components/schemas/LegMetadata'
FlightMetadata:
title: FlightMetadata
description: Flight metadata against which document is associated.
type: object
properties:
flightId:
type: string
description: Unique identifier of the flight.
example: CgNERU4SA1NGTxoKNTQ1NzI5ODcxMQ
PostalAddress:
title: PostalAddress
description: Postal Address Details
type: object
required:
- addressLines
- regionCode
properties:
addressLines:
description: Address lines
type: array
items:
type: string
example: Golden Gate Bridge
administrativeArea:
type: string
description: 'Code of administrative area. For example: DL for Delhi, India.
Highest administrative subdivision which is used for postal
addresses of a country or region.
For example, this can be a state, a province, an oblast, or a prefecture.
Specifically, for Spain this is the province and not the autonomous
community (e.g. "Barcelona" and not "Catalonia").
Many countries don''t use an administrative area in postal addresses. E.g.
in Switzerland this should be left unpopulated.
'
example: CA
administrativeAreaName:
type: string
description: "Name of administrative area. This is full name corresponding to administrativeArea. \nLike Delhi for DL area code. For some places, code and name maybe same as well like Tokyo.\n"
example: California
description:
description: Address description
type: string
example: San Francisco Home
isDefault:
description: Whether this address is default address in case multiple addresses are specified.
type: boolean
example: true
languageCode:
description: "BCP-47 language code of the contents of this address (if known). This is often the UI \nlanguage of the input form or is expected to match one of the languages used in the \naddress' country/region, or their transliterated equivalents.\nThis can affect formatting in certain countries, but is not critical to the correctness \nof the data and will never affect any validation or other non-formatting related operations.\nExamples: \"zh-Hant\", \"ja\", \"ja-Latn\", \"en\".\n"
type: string
example: en
locality:
description: Generally refers to the city/town portion of the address.
type: string
example: San Francisco
locationCode:
description: IATA 3-letter location code. See https://www.iata.org/en/services/codes.
type: string
example: LAX
organization:
description: The name of the organization at the address.
type: string
example: Spotnana
postalCode:
description: Postal code of the address. This is a required field when setting for a user/legal entity/company etc.
type: string
example: '94130'
continentCode:
description: 2 letter continent code of the continent this address falls in.
type: string
example: AF
recipients:
description: The recipient at the address.
type: array
items:
type: string
regionCode:
description: Region code of the country/region of the address.
type: string
example: US
regionName:
description: Region name of the country/region of the address.
type: string
example: America
revision:
type: integer
format: int32
example: 1
sortingCode:
description: 'Additional, country-specific, sorting code. This is not used
in most regions. Where it is used, the value is either a string like
"CEDEX", optionally followed by a number (e.g. "CEDEX 7"), or just a number
alone, representing the "sector code" (Jamaica), "delivery area indicator"
(Malawi) or "post office indicator" (e.g. Côte d''Ivoire).
'
type: string
example: Jamaica
sublocality:
description: Sublocality of the address. This can be neighborhoods, boroughs, districts.
type: string
timezone:
description: Time zone of the address.
type: string
example: America/Los_Angeles
coordinates:
description: Map coordinates of the address.
$ref: '#/components/schemas/Latlng'
ErrorParameter:
type: object
title: ErrorParameter
description: Error parameter
properties:
name:
type: string
description: Parameter name
value:
type: string
description: Parameter value
DocumentMetadata:
title: DocumentMetadata
description: Metadata related to document.
type: object
required:
- documentType
- entityType
- entityId
- entityMetadata
- name
properties:
documentType:
$ref: '#/components/schemas/DocumentType'
entityType:
$ref: '#/components/schemas/EntityType'
entityId:
type: string
description: Entity Id for the given entity type.
example: '123124'
entityMetadata:
$ref: '#/components/schemas/EntityMetadata'
name:
type: string
description: Document name.
example: BoardingPass.pdf
GetDocumentsResponse:
type: object
title: GetDocumentsResponse
description: Response containing a list of documents.
required:
- documents
properties:
documents:
type: array
description: List of documents.
items:
$ref: '#/components/schemas/Document'
LegMetadata:
title: LegMetadata
description: Leg metadata against which document is associated.
type: object
properties:
legId:
type: string
description: Unique identifier of the leg.
example: CgNTRk8SA0RFThoKNTQ1NzI5ODcxMQ==
UploadDocumentResponse:
type: object
title: UploadDocumentResponse
description: Response for upload document.
required:
- documentId
- documentMetadata
properties:
documentId:
type: string
format: uuid
description: Unique identifier of the document.
example: f49d00fe-1eda-4304-ba79-a980f565281d
documentMetadata:
$ref: '#/components/schemas/DocumentMetadata'
EventEntityMetadata:
title: EventEntityMetadata
description: Metadata when document is associated to an event.
type: object
properties:
address:
$ref: '#/components/schemas/PostalAddress'
responses:
Forbidden:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
NotFound:
description: The specified resource was not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Unauthorized:
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
securitySchemes:
Bearer:
type: http
scheme: bearer