455 lines
14 KiB
Plaintext
455 lines
14 KiB
Plaintext
openapi: 3.0.3
|
|
info:
|
|
title: Google Drive HTTP Proxy Adapter API
|
|
description: |
|
|
HTTP proxy adapter for exporting Google Drive documents in multiple formats (Markdown, HTML, PDF)
|
|
and generating XML sitemaps of accessible documents.
|
|
|
|
## Authentication
|
|
The adapter uses OAuth 2.0 to access Google Drive on behalf of configured users.
|
|
External clients do not need to authenticate with this API directly.
|
|
|
|
## Rate Limiting
|
|
API requests are rate-limited to 100 requests per minute per IP address.
|
|
Rate limit information is included in response headers.
|
|
version: 1.0.0
|
|
contact:
|
|
name: API Support
|
|
license:
|
|
name: MIT
|
|
|
|
servers:
|
|
- url: http://localhost:3000
|
|
description: Development server
|
|
- url: https://api.example.com
|
|
description: Production server
|
|
|
|
tags:
|
|
- name: Documents
|
|
description: Document export operations
|
|
- name: Discovery
|
|
description: Document discovery and listing
|
|
- name: Health
|
|
description: Service health monitoring
|
|
|
|
paths:
|
|
/health:
|
|
get:
|
|
summary: Health check endpoint
|
|
description: Returns service health status and version information
|
|
tags:
|
|
- Health
|
|
responses:
|
|
'200':
|
|
description: Service is healthy
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
status:
|
|
type: string
|
|
example: ok
|
|
version:
|
|
type: string
|
|
example: 1.0.0
|
|
uptime:
|
|
type: number
|
|
description: Service uptime in seconds
|
|
example: 86400
|
|
|
|
/sitemap.xml:
|
|
get:
|
|
summary: Generate sitemap of accessible documents
|
|
description: |
|
|
Returns an XML sitemap listing all Google Drive documents accessible to the configured user.
|
|
Follows the sitemap protocol specification (https://www.sitemaps.org/protocol.html).
|
|
tags:
|
|
- Discovery
|
|
responses:
|
|
'200':
|
|
description: Sitemap generated successfully
|
|
headers:
|
|
Content-Type:
|
|
schema:
|
|
type: string
|
|
example: application/xml; charset=utf-8
|
|
X-Request-Id:
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
description: Unique request identifier for tracing
|
|
X-Document-Count:
|
|
schema:
|
|
type: integer
|
|
description: Number of documents in the sitemap
|
|
content:
|
|
application/xml:
|
|
schema:
|
|
type: string
|
|
format: xml
|
|
example: |
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
<url>
|
|
<loc>http://localhost:3000/1BxAA_example123</loc>
|
|
<lastmod>2026-03-06T10:30:00Z</lastmod>
|
|
</url>
|
|
<url>
|
|
<loc>http://localhost:3000/2CyBB_example456</loc>
|
|
<lastmod>2026-03-05T14:20:00Z</lastmod>
|
|
</url>
|
|
</urlset>
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'429':
|
|
$ref: '#/components/responses/RateLimited'
|
|
'500':
|
|
$ref: '#/components/responses/InternalError'
|
|
'503':
|
|
$ref: '#/components/responses/ServiceUnavailable'
|
|
|
|
/{documentId}:
|
|
get:
|
|
summary: Export Google Drive document in specified format
|
|
description: |
|
|
Fetches a Google Drive document by ID and exports it in the requested format.
|
|
Supports Markdown (default), HTML, and PDF formats.
|
|
tags:
|
|
- Documents
|
|
parameters:
|
|
- name: documentId
|
|
in: path
|
|
required: true
|
|
description: Google Drive file ID (8-128 alphanumeric characters, hyphens, or underscores)
|
|
schema:
|
|
type: string
|
|
pattern: '^[a-zA-Z0-9_-]{8,128}$'
|
|
example: 1BxAA_example123
|
|
|
|
- name: format
|
|
in: query
|
|
required: false
|
|
description: Export format (defaults to markdown if not specified)
|
|
schema:
|
|
type: string
|
|
enum:
|
|
- markdown
|
|
- html
|
|
- pdf
|
|
default: markdown
|
|
example: markdown
|
|
|
|
responses:
|
|
'200':
|
|
description: Document exported successfully
|
|
headers:
|
|
Content-Type:
|
|
schema:
|
|
type: string
|
|
enum:
|
|
- text/markdown; charset=utf-8
|
|
- text/html; charset=utf-8
|
|
- application/pdf
|
|
description: MIME type of exported document
|
|
X-Request-Id:
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
description: Unique request identifier for tracing
|
|
X-Document-Title:
|
|
schema:
|
|
type: string
|
|
description: Original document title from Google Drive
|
|
X-Document-Modified:
|
|
schema:
|
|
type: string
|
|
format: date-time
|
|
description: Last modified timestamp (ISO 8601)
|
|
content:
|
|
text/markdown:
|
|
schema:
|
|
type: string
|
|
example: |
|
|
# Document Title
|
|
|
|
This is a paragraph with **bold** and *italic* text.
|
|
|
|
## Section Heading
|
|
|
|
- List item 1
|
|
- List item 2
|
|
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
example: |
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head><title>Document Title</title></head>
|
|
<body>
|
|
<h1>Document Title</h1>
|
|
<p>This is a paragraph with <strong>bold</strong> and <em>italic</em> text.</p>
|
|
</body>
|
|
</html>
|
|
|
|
application/pdf:
|
|
schema:
|
|
type: string
|
|
format: binary
|
|
|
|
'400':
|
|
$ref: '#/components/responses/BadRequest'
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'413':
|
|
$ref: '#/components/responses/PayloadTooLarge'
|
|
'415':
|
|
$ref: '#/components/responses/UnsupportedMediaType'
|
|
'429':
|
|
$ref: '#/components/responses/RateLimited'
|
|
'500':
|
|
$ref: '#/components/responses/InternalError'
|
|
'503':
|
|
$ref: '#/components/responses/ServiceUnavailable'
|
|
|
|
components:
|
|
schemas:
|
|
ErrorResponse:
|
|
type: object
|
|
required:
|
|
- error
|
|
- timestamp
|
|
properties:
|
|
error:
|
|
type: object
|
|
required:
|
|
- code
|
|
- message
|
|
- requestId
|
|
properties:
|
|
code:
|
|
type: string
|
|
description: Machine-readable error code
|
|
enum:
|
|
- DOCUMENT_NOT_FOUND
|
|
- DOCUMENT_FORBIDDEN
|
|
- UNAUTHORIZED
|
|
- INVALID_FORMAT
|
|
- UNSUPPORTED_DOCUMENT_TYPE
|
|
- RATE_LIMITED
|
|
- DRIVE_API_ERROR
|
|
- INTERNAL_ERROR
|
|
- PAYLOAD_TOO_LARGE
|
|
example: DOCUMENT_NOT_FOUND
|
|
message:
|
|
type: string
|
|
description: Human-readable error message
|
|
example: Document with ID '1BxAA_example123' does not exist or is not accessible
|
|
details:
|
|
type: object
|
|
description: Optional additional context
|
|
additionalProperties: true
|
|
requestId:
|
|
type: string
|
|
format: uuid
|
|
description: Request ID for support and debugging
|
|
example: 550e8400-e29b-41d4-a716-446655440000
|
|
timestamp:
|
|
type: string
|
|
format: date-time
|
|
description: ISO 8601 timestamp when error occurred
|
|
example: '2026-03-06T10:30:00.123Z'
|
|
|
|
responses:
|
|
BadRequest:
|
|
description: Invalid request parameters
|
|
headers:
|
|
X-Request-Id:
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
error:
|
|
code: INVALID_FORMAT
|
|
message: "Invalid format 'docx'. Supported formats: markdown, html, pdf"
|
|
requestId: 550e8400-e29b-41d4-a716-446655440000
|
|
timestamp: '2026-03-06T10:30:00.123Z'
|
|
|
|
Unauthorized:
|
|
description: Authentication failed or missing
|
|
headers:
|
|
X-Request-Id:
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
error:
|
|
code: UNAUTHORIZED
|
|
message: Authentication with Google Drive failed
|
|
requestId: 550e8400-e29b-41d4-a716-446655440001
|
|
timestamp: '2026-03-06T10:30:01.456Z'
|
|
|
|
Forbidden:
|
|
description: User lacks permission to access the document
|
|
headers:
|
|
X-Request-Id:
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
error:
|
|
code: DOCUMENT_FORBIDDEN
|
|
message: You do not have permission to access this document
|
|
requestId: 550e8400-e29b-41d4-a716-446655440002
|
|
timestamp: '2026-03-06T10:30:02.789Z'
|
|
|
|
NotFound:
|
|
description: Document does not exist
|
|
headers:
|
|
X-Request-Id:
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
error:
|
|
code: DOCUMENT_NOT_FOUND
|
|
message: Document with ID '1BxAA_invalid' does not exist or is not accessible
|
|
requestId: 550e8400-e29b-41d4-a716-446655440003
|
|
timestamp: '2026-03-06T10:30:03.012Z'
|
|
|
|
PayloadTooLarge:
|
|
description: Document exceeds maximum size limit
|
|
headers:
|
|
X-Request-Id:
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
error:
|
|
code: PAYLOAD_TOO_LARGE
|
|
message: Document size exceeds maximum limit of 100MB
|
|
requestId: 550e8400-e29b-41d4-a716-446655440004
|
|
timestamp: '2026-03-06T10:30:04.345Z'
|
|
|
|
UnsupportedMediaType:
|
|
description: Document type cannot be exported in requested format
|
|
headers:
|
|
X-Request-Id:
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
error:
|
|
code: UNSUPPORTED_DOCUMENT_TYPE
|
|
message: Document type 'application/vnd.google-apps.form' cannot be exported as PDF
|
|
requestId: 550e8400-e29b-41d4-a716-446655440005
|
|
timestamp: '2026-03-06T10:30:05.678Z'
|
|
|
|
RateLimited:
|
|
description: Rate limit exceeded
|
|
headers:
|
|
X-Request-Id:
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
X-RateLimit-Limit:
|
|
schema:
|
|
type: integer
|
|
description: Maximum requests per minute
|
|
example: 100
|
|
X-RateLimit-Remaining:
|
|
schema:
|
|
type: integer
|
|
description: Remaining requests in current window
|
|
example: 0
|
|
X-RateLimit-Reset:
|
|
schema:
|
|
type: integer
|
|
description: Unix timestamp when rate limit resets
|
|
example: 1709724660
|
|
Retry-After:
|
|
schema:
|
|
type: integer
|
|
description: Seconds until rate limit resets
|
|
example: 60
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
error:
|
|
code: RATE_LIMITED
|
|
message: Rate limit exceeded. Please retry after 60 seconds
|
|
requestId: 550e8400-e29b-41d4-a716-446655440006
|
|
timestamp: '2026-03-06T10:30:06.901Z'
|
|
|
|
InternalError:
|
|
description: Internal server error
|
|
headers:
|
|
X-Request-Id:
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
error:
|
|
code: INTERNAL_ERROR
|
|
message: An unexpected error occurred while processing your request
|
|
requestId: 550e8400-e29b-41d4-a716-446655440007
|
|
timestamp: '2026-03-06T10:30:07.234Z'
|
|
|
|
ServiceUnavailable:
|
|
description: Service temporarily unavailable (Google Drive API down or rate limited)
|
|
headers:
|
|
X-Request-Id:
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
Retry-After:
|
|
schema:
|
|
type: integer
|
|
description: Seconds until service may be available
|
|
example: 300
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
error:
|
|
code: DRIVE_API_ERROR
|
|
message: Google Drive API is temporarily unavailable. Please retry later
|
|
requestId: 550e8400-e29b-41d4-a716-446655440008
|
|
timestamp: '2026-03-06T10:30:08.567Z'
|