From 6fc508ecb1060fac48bffdafd7c63c0a284c9b05 Mon Sep 17 00:00:00 2001 From: Ronan Harris Date: Thu, 13 Nov 2025 15:53:26 +0000 Subject: [PATCH 1/2] Initial commit: Nitro Platform API integration examples --- .gitignore | 14 + README.md | 72 + docs/API-overview.md | 74 + docs/workflow-examples.md | 104 + postman/Platform-API.postman_collection.json | 2133 ++++++++++++++++++ postman/README.md | 72 + power-automate/README.md | 89 + samples/python/.env.example | 3 + samples/python/README.md | 47 + samples/python/quickstart.py | 71 + samples/python/requirements.txt | 2 + 11 files changed, 2681 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 docs/API-overview.md create mode 100644 docs/workflow-examples.md create mode 100755 postman/Platform-API.postman_collection.json create mode 100644 postman/README.md create mode 100644 power-automate/README.md create mode 100644 samples/python/.env.example create mode 100644 samples/python/README.md create mode 100644 samples/python/quickstart.py create mode 100644 samples/python/requirements.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..74b28a0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# Environment variables +.env + +# Python +__pycache__/ +*.pyc + +# OS +.DS_Store + +# API keys and secrets +*secret* +*key* +*token* diff --git a/README.md b/README.md new file mode 100644 index 0000000..8675a33 --- /dev/null +++ b/README.md @@ -0,0 +1,72 @@ +# Nitro Platform API Integrations + +This repository provides examples and tools for integrating with the Nitro Platform API, enabling document conversion, extraction, transformation, and workflow automation. + +## What is the Platform API? + +The Nitro Platform API provides programmatic access to document processing capabilities including: +- **Document Conversions**: Convert between formats (Word↔PDF, Excel→PDF, PowerPoint→PDF, etc.) +- **Data Extraction**: Extract text, form data, tables, and detect PII from documents +- **Document Transformations**: Compress, merge, split, redact, password protect, and more +- **Async Processing**: Handle large documents with job-based workflows + +## Repository Structure + +``` +├── postman/ # Postman collection and environment +├── power-automate/ # Custom connector and sample flows +├── samples/ +│ └── python/ # Python examples +└── docs/ # API documentation and guides +``` + +## Getting Started + +### Prerequisites + +1. **API Access**: Get OAuth2 client credentials: + - Go to [https://admin.gonitro.com](https://admin.gonitro.com) + - Navigate to **Settings** → **API** + - Click **Create Application** + - Name your application and save the Client ID and Client Secret + +2. **Environment Setup**: Set the following variables: + ```bash + export PLATFORM_BASE_URL=https://api.gonitro.dev + export PLATFORM_CLIENT_ID= + export PLATFORM_CLIENT_SECRET= + ``` + +### Quick Start Options + +#### Using Postman +1. Import the collection from `postman/Platform-API.postman_collection.json` +2. Configure environment variables (see `postman/README.md`) +3. Get a bearer token and run sample requests + +#### Using Power Automate +1. Create a custom connector using instructions in `power-automate/` +2. Configure API key authentication +3. Build flows for document processing workflows + +#### Using Sample Code +- **Python**: See `samples/python/README.md` + +## Authentication + +The API uses OAuth2 authentication: +1. Exchange client credentials for an access token via `POST /oauth/token` +2. Include the token in requests: `Authorization: Bearer ` + +See the [authentication documentation](https://developers.gonitro.com/docs/api-reference/authentication/get-access-token) for details. + +## Common Workflows + +- **Document Conversion**: Upload a file → Get converted result +- **Async Processing**: Start job → Poll status → Download result +- **Data Extraction**: Upload PDF → Extract text/tables/forms +- **Document Transformation**: Upload PDF → Apply operations → Download result + +## Support + +For API documentation and support, visit the [developer portal](https://developers.gonitro.dev). diff --git a/docs/API-overview.md b/docs/API-overview.md new file mode 100644 index 0000000..c4b29a5 --- /dev/null +++ b/docs/API-overview.md @@ -0,0 +1,74 @@ +# API Overview + +The Nitro Platform API provides document processing capabilities through a RESTful interface. + +## Base URL + +All API requests are made to: `https://api.gonitro.dev` + +## Authentication + +The API uses OAuth2 client credentials flow: + +1. **Get Credentials**: Create an application at [admin.gonitro.com](https://admin.gonitro.com) → Settings → API +2. **Get Token**: Exchange credentials for access token via `POST /oauth/token` +3. **Use Token**: Include in requests as `Authorization: Bearer ` + +## Request/Response Patterns + +### Synchronous Operations +- Submit request with file +- Get immediate response with result +- Best for: Small files, simple operations + +### Asynchronous Operations +- Submit request, get job ID +- Poll `/jobs/{jobId}/status` for progress +- Download result when complete +- Best for: Large files, complex operations + +## API Categories + +### Conversions (`/platform/conversions`) +Convert documents between formats: +- Word ↔ PDF +- Excel → PDF +- PowerPoint → PDF +- Images → PDF + +### Extractions (`/platform/extractions`) +Extract data from documents: +- Text extraction +- Form data extraction +- Table data extraction +- PII detection + +### Transformations (`/platform/transformations`) +Modify PDF documents: +- Compress, merge, split +- Redact content +- Password protect/remove +- Rotate/delete pages + +### Jobs (`/jobs`) +Manage asynchronous operations: +- Check job status +- Download job results +- Handle job errors + +## Error Handling + +The API returns standard HTTP status codes: +- `200` - Success +- `400` - Bad Request (invalid parameters) +- `401` - Unauthorized (invalid/missing token) +- `404` - Not Found (invalid endpoint/job ID) +- `500` - Internal Server Error + +Error responses include details: +```json +{ + "error": "Invalid file format", + "message": "Only PDF files are supported for this operation" +} +``` diff --git a/docs/workflow-examples.md b/docs/workflow-examples.md new file mode 100644 index 0000000..e2cf880 --- /dev/null +++ b/docs/workflow-examples.md @@ -0,0 +1,104 @@ +# Workflow Examples + +Common end-to-end workflows using the Platform API. + +## Document Conversion Workflow + +**Goal**: Convert Word documents to PDF + +### Using Postman +1. Run "Get Bearer Token" request +2. Use "Word → PDF" request with your .docx file +3. Download the converted PDF from response + +### Using Python +```python +token = get_access_token(client_id, client_secret) +with open('document.docx', 'rb') as f: + result = convert_to_pdf(token, f) +with open('document.pdf', 'wb') as f: + f.write(result) +``` + +### Using Power Automate +1. **Trigger**: When file added to SharePoint +2. **Action**: Convert using custom connector +3. **Action**: Save result back to SharePoint + +## Data Extraction Workflow + +**Goal**: Extract text and tables from PDF invoices + +### Steps +1. **Upload PDF**: Submit to `/platform/extractions/pdf-text` +2. **Extract Tables**: Submit to `/platform/extractions/pdf-table-data` +3. **Process Data**: Parse extracted JSON for relevant fields +4. **Store Results**: Save to database/spreadsheet + +### Use Cases +- Invoice processing +- Form data extraction +- Document analysis +- Content migration + +## Async Processing Workflow + +**Goal**: Process large documents without timeouts + +### Steps +1. **Submit Job**: POST to conversion/extraction endpoint +2. **Get Job ID**: Note the `jobId` from response +3. **Poll Status**: GET `/jobs/{jobId}/status` until `status: "completed"` +4. **Download Result**: GET `/jobs/{jobId}/result` + +### Implementation Pattern +```python +# Submit job +job_response = submit_conversion_job(token, file_data) +job_id = job_response['jobId'] + +# Poll until complete +while True: + status = get_job_status(token, job_id) + if status['status'] == 'completed': + break + elif status['status'] == 'failed': + raise Exception(f"Job failed: {status['message']}") + time.sleep(5) # Wait 5 seconds before next check + +# Download result +result = get_job_result(token, job_id) +``` + +## Batch Processing Workflow + +**Goal**: Process multiple documents efficiently + +### Strategy +1. **Queue Jobs**: Submit all files as async jobs +2. **Track Progress**: Monitor all job IDs +3. **Download Results**: Collect completed results +4. **Handle Errors**: Retry failed jobs + +### Best Practices +- Use async processing for files > 10MB +- Add delays between API calls (rate limiting) +- Implement retry logic for failed requests +- Log all operations for debugging + +## Document Pipeline Workflow + +**Goal**: Complete document processing pipeline + +### Example: Invoice Processing +1. **Convert**: Word/Excel invoices → PDF +2. **Extract**: Text and table data from PDFs +3. **Validate**: Check extracted data quality +4. **Transform**: Redact sensitive information +5. **Store**: Save processed documents and data + +### Integration Points +- **Input**: SharePoint, OneDrive, email attachments +- **Processing**: Platform API operations +- **Output**: Database, CRM, accounting system +- **Notifications**: Email, Teams, Slack alerts diff --git a/postman/Platform-API.postman_collection.json b/postman/Platform-API.postman_collection.json new file mode 100755 index 0000000..deec692 --- /dev/null +++ b/postman/Platform-API.postman_collection.json @@ -0,0 +1,2133 @@ +{ + "info": { + "_postman_id": "b9794fa2-0560-41b7-ac41-124b067fe372", + "name": "Nitro Automation Platform APIs", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "49176897", + "_collection_link": "https://connective.postman.co/workspace/Personal-Workspace~a573f67d-3b8e-48d5-9420-74f34a276738/collection/49176897-b9794fa2-0560-41b7-ac41-124b067fe372?action=share&source=collection_link&creator=49176897" + }, + "item": [ + { + "name": "Authorization", + "item": [ + { + "name": "Get Bearer Token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Parse the response", + "let responseData = pm.response.json();", + "", + "// Store token in an environment variable", + "pm.environment.set(\"token\", responseData.accessToken);", + "", + "// Optional: Log it to the Postman console", + "console.log(\"Token saved:\", responseData.token);" + ], + "type": "text/javascript", + "packages": {}, + "requests": {} + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"clientID\": \"{{clientID}}\",\n \"clientSecret\": \"{{clientSecret}}\"\n}" + }, + "url": { + "raw": "{{baseUrl}}/oauth/token", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "oauth", + "token" + ] + }, + "description": "Generated from cURL: curl --request POST \\\n --url https://api.gonitro.dev/oauth/token \\\n --header 'Content-Type: application/json' \\\n --data '{\n \"clientID\": \"\",\n \"clientSecret\": \"\"\n}'" + }, + "response": [] + } + ], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "// Authorization folder: Validate status codes and response structure", + "pm.test(\"Status code is 200 or 201\", function () {", + " pm.expect(pm.response.code).to.be.oneOf([200, 201]);", + "});", + "pm.test(\"Response has expected properties\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.be.an('object');", + " pm.expect(jsonData).to.have.any.keys('access_token', 'token_type', 'expires_in');", + "});" + ] + } + } + ] + }, + { + "name": "Conversions", + "item": [ + { + "name": "Word → PDF", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "convert" + }, + { + "key": "params", + "value": "{\"to\": \"pdf\"}" + }, + { + "key": "file", + "type": "file", + "src": "Analysis.docx" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/conversions", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "conversions" + ] + }, + "description": "Upload a Word document (.doc, .docx, .dot, .xml, .docm, .dotx, .dotm, .rtf) and convert to PDF." + }, + "response": [] + }, + { + "name": "Excel → PDF", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "convert" + }, + { + "key": "params", + "value": "{\"to\": \"pdf\"}" + }, + { + "key": "file", + "type": "file", + "src": "Feedback.xlsx" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/conversions", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "conversions" + ] + }, + "description": "Upload an Excel workbook (.xlsx, .xls, .xlt, .xlsm, .xltx, .xltm) and convert to PDF." + }, + "response": [] + }, + { + "name": "PowerPoint → PDF", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "convert" + }, + { + "key": "params", + "value": "{\"to\": \"pdf\"}" + }, + { + "key": "file", + "value": "", + "type": "file" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/conversions", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "conversions" + ] + }, + "description": "Upload a PowerPoint file (.pptx, .ppt) and convert to PDF." + }, + "response": [] + }, + { + "name": "Image → PDF", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "convert" + }, + { + "key": "params", + "value": "{\"to\": \"pdf\"}" + }, + { + "key": "file", + "type": "file", + "src": "GoNitro.png" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/conversions", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "conversions" + ] + }, + "description": "Upload an image (.png, .jpg, .jpeg, .tiff) and convert to PDF." + }, + "response": [] + }, + { + "name": "PDF → Word", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "convert" + }, + { + "key": "params", + "value": "{\"to\": \"docx\"}" + }, + { + "key": "file", + "type": "file", + "src": "SampleResume.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/conversions", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "conversions" + ] + }, + "description": "Upload a PDF and convert to Word (docx)." + }, + "response": [] + }, + { + "name": "PDF → Excel", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "convert" + }, + { + "key": "params", + "value": "{\"to\": \"xlsx\"}" + }, + { + "key": "file", + "type": "file", + "src": "Sample Tables.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/conversions", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "conversions" + ] + }, + "description": "Upload a PDF and convert to Excel (xlsx)." + }, + "response": [] + }, + { + "name": "PDF → Image", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "convert" + }, + { + "key": "params", + "value": "{\"to\": \"png\"}" + }, + { + "key": "file", + "type": "file", + "src": "SampleResume.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/conversions", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "conversions" + ] + }, + "description": "Upload a PDF and convert to image (png/jpg). Modify the `to` field for the desired format." + }, + "response": [] + } + ], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "// Conversions folder: Validate status codes and response structure", + "pm.test(\"Status code is 200 or 201\", function () {", + " pm.expect(pm.response.code).to.be.oneOf([200, 201]);", + "});", + "pm.test(\"Response has expected properties\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.be.an('object');", + " pm.expect(jsonData).to.have.any.keys('jobId', 'status', 'outputUrl');", + "});" + ] + } + } + ] + }, + { + "name": "Extractions", + "item": [ + { + "name": "Extract PDF Text", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "extract-text" + }, + { + "key": "params", + "value": "{}" + }, + { + "key": "file", + "type": "file", + "src": "SampleResume.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/extractions", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "extractions" + ] + }, + "description": "Extract plain text from the file." + }, + "response": [] + }, + { + "name": "Extract PDF Form Data", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "extract-forms" + }, + { + "key": "params", + "value": "{}" + }, + { + "key": "file", + "type": "file", + "src": "BOB - Student-Loan-Application-Form.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/extractions", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "extractions" + ] + }, + "description": "Extract form field data." + }, + "response": [] + }, + { + "name": "Extract PDF Table Data", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "extract-tables" + }, + { + "key": "params", + "value": "{}" + }, + { + "key": "file", + "type": "file", + "src": "Sample Tables.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/extractions", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "extractions" + ] + }, + "description": "Extract tabular data." + }, + "response": [] + }, + { + "name": "Extract and Autodetect Bounding Boxes for PII", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "pii-bbox-extraction" + }, + { + "key": "params", + "value": "{\"language\":\"en\"}" + }, + { + "key": "file", + "type": "file", + "src": "SampleResume.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/extractions", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "extractions" + ] + }, + "description": "Detect PII and return bounding boxes." + }, + "response": [] + }, + { + "name": "Extract Bounding Boxes for Strings", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "text-bbox-extraction" + }, + { + "key": "params", + "value": "{ \"texts\": [ \"Professional\", \"Location\" ]}" + }, + { + "key": "file", + "type": "file", + "src": "SampleResume.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/extractions", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "extractions" + ] + }, + "description": "Return coordinates for given strings." + }, + "response": [] + }, + { + "name": "Get PDF Properties", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "get-properties" + }, + { + "key": "params", + "value": "{}" + }, + { + "key": "file", + "type": "file", + "src": "SampleResume.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/extractions", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "extractions" + ] + }, + "description": "Return document properties/metadata." + }, + "response": [] + }, + { + "name": "Set PDF Properties", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "set-properties" + }, + { + "key": "params", + "value": "{\"title\": \"the-title\"}" + }, + { + "key": "file", + "type": "file", + "src": "SampleResume.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/transformations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "transformations" + ] + }, + "description": "Set document properties/metadata." + }, + "response": [] + } + ], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "// Extractions folder: Validate status codes and response structure", + "pm.test(\"Status code is 200 or 201\", function () {", + " pm.expect(pm.response.code).to.be.oneOf([200, 201]);", + "});", + "pm.test(\"Response has expected properties\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.be.an('object');", + " pm.expect(jsonData).to.have.any.keys('extractedData', 'status');", + "});" + ] + } + } + ] + }, + { + "name": "Transformations", + "item": [ + { + "name": "Redact Bounding boxes (scrub PII)", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "redact" + }, + { + "key": "params", + "value": "{\n \"redactions\": [\n {\n \"pageIndex\": 0,\n \"boundingBox\": [\n 0.181746726,\n 0.170494927,\n 0.308388903,\n 0.188994937\n ],\n \"PIIType\": \"PHONE\",\n \"confidence\": 0.99\n },\n {\n \"pageIndex\": 0,\n \"boundingBox\": [\n 0.117687911,\n 0.106075797,\n 0.234256545,\n 0.124575798\n ],\n \"PIIType\": \"NAME\",\n \"confidence\": 0.99\n }\n ]\n}\n" + }, + { + "key": "file", + "type": "file", + "src": "SampleResume.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/transformations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "transformations" + ] + }, + "description": "Redact sensitive data from documents." + }, + "response": [] + }, + { + "name": "Compress", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "compress" + }, + { + "key": "params", + "value": "{\"level\": 2}" + }, + { + "key": "file", + "type": "file", + "src": "BOB - Student-Loan-Application-Form.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/transformations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "transformations" + ] + }, + "description": "Compress the PDF size." + }, + "response": [] + }, + { + "name": "Flatten", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "flatten" + }, + { + "key": "params", + "value": "{}" + }, + { + "key": "file", + "type": "file", + "src": "Sample Tables.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/transformations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "transformations" + ] + }, + "description": "Flatten annotations/form fields." + }, + "response": [] + }, + { + "name": "Rotate Pages", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "rotate" + }, + { + "key": "params", + "value": "{ \"rotations\": [ { \"page_index\": 0, \"amount\": 90 }, { \"page_index\": 1, \"amount\": -90 } ]}" + }, + { + "key": "file", + "type": "file", + "src": "SampleResume.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/transformations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "transformations" + ] + }, + "description": "Rotate pages by angle." + }, + "response": [] + }, + { + "name": "Delete Pages", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "delete-pages" + }, + { + "key": "params", + "value": "{\n\t\"pageIndices\": [\n\t\t0,\n\t\t2\n\t]\n}" + }, + { + "key": "file", + "type": "file", + "src": "SampleResume.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/transformations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "transformations" + ] + }, + "description": "Delete specific pages." + }, + "response": [] + }, + { + "name": "Split", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "split" + }, + { + "key": "params", + "value": "{ \"pageIndices\": [ [0, 2], [1, 3, 4] ]}" + }, + { + "key": "file", + "type": "file", + "src": "SampleResume.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/transformations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "transformations" + ] + }, + "description": "Split a document into parts." + }, + "response": [] + }, + { + "name": "Merge", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "merge" + }, + { + "key": "params", + "value": "{}" + }, + { + "key": "file", + "type": "file", + "src": [ + "Sample Tables.pdf", + "SampleResume.pdf" + ] + }, + { + "key": "file2", + "type": "file", + "src": [] + } + ] + }, + "url": { + "raw": "{{baseUrl}}/transformations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "transformations" + ] + }, + "description": "Merge multiple documents together." + }, + "response": [] + }, + { + "name": "Password Protect", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "protect" + }, + { + "key": "params", + "value": "{\"ownerPassword\": \"secret\", \"userPassword\": \"open\"}" + }, + { + "key": "file", + "type": "file", + "src": "SampleResume.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/transformations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "transformations" + ] + }, + "description": "Add password protection." + }, + "response": [] + }, + { + "name": "Password Remove", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "unprotect" + }, + { + "key": "params", + "value": "{\"ownerPassword\": \"secret\"}" + }, + { + "key": "file", + "type": "file", + "src": "PDF-withpassword.pdf" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/transformations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "transformations" + ] + }, + "description": "Remove password protection." + }, + "response": [] + } + ], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "// Transformations folder: Validate status codes and response structure", + "pm.test(\"Status code is 200 or 201\", function () {", + " pm.expect(pm.response.code).to.be.oneOf([200, 201]);", + "});", + "pm.test(\"Response has expected properties\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.be.an('object');", + " pm.expect(jsonData).to.have.any.keys('jobId', 'status', 'transformedData');", + "});" + ] + } + } + ] + }, + { + "name": "Jobs", + "item": [ + { + "name": "Get Async Job Status", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + } + ], + "url": { + "raw": "{{baseUrl}}/jobs/{{jobId}}/status", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "jobs", + "{{jobId}}", + "status" + ] + }, + "description": "Fetch status for an asynchronous job by ID." + }, + "response": [] + }, + { + "name": "Get Async Job Result", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + } + ], + "url": { + "raw": "{{baseUrl}}/jobs/{{jobId}}/result", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "jobs", + "{{jobId}}", + "result" + ] + }, + "description": "Retrieve the result for an asynchronous job by ID." + }, + "response": [] + } + ], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "// Jobs folder: Validate status codes and response structure", + "pm.test(\"Status code is 200 or 201\", function () {", + " pm.expect(pm.response.code).to.be.oneOf([200, 201]);", + "});", + "pm.test(\"Response has expected properties\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.be.an('object');", + " pm.expect(jsonData).to.have.any.keys('jobId', 'status', 'createdAt');", + "});" + ] + } + } + ] + }, + { + "name": "Work in Progress", + "item": [ + { + "name": "ToDo - Add Accessibility (Alt Text)", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "add-accessibility" + }, + { + "key": "params", + "value": "{\"altText\": [{\"page\": 1, \"objectId\": \"img1\", \"text\": \"Chart of sales\"}]}" + }, + { + "key": "delivery", + "value": "" + }, + { + "key": "file", + "value": "", + "type": "file" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/transformations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "transformations" + ] + }, + "description": "Add accessibility metadata such as alt text for images." + }, + "response": [] + }, + { + "name": "ToDo - Quick Sign", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "sign" + }, + { + "key": "params", + "value": "{\"signature\": \"\"}" + }, + { + "key": "delivery", + "value": "" + }, + { + "key": "file", + "value": "", + "type": "file" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/transformations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "transformations" + ] + }, + "description": "Apply a simple e-signature." + }, + "response": [] + }, + { + "name": "ToDo - Fill Form", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "fill" + }, + { + "key": "params", + "value": "{\"fields\": {\"Name\": \"Ada Lovelace\"}}" + }, + { + "key": "delivery", + "value": "" + }, + { + "key": "file", + "value": "", + "type": "file" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/transformations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "transformations" + ] + }, + "description": "Programmatically fill PDF forms." + }, + "response": [] + }, + { + "name": "ToDo - Find & Replace Text", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "find-and-replace" + }, + { + "key": "params", + "value": "{\"find\": \"foo\", \"replace\": \"bar\"}" + }, + { + "key": "delivery", + "value": "" + }, + { + "key": "file", + "value": "", + "type": "file" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/transformations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "transformations" + ] + }, + "description": "Find and replace text." + }, + "response": [] + }, + { + "name": "ToDo - Apply OCR", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "ocr" + }, + { + "key": "params", + "value": "{\"lang\": \"eng\"}" + }, + { + "key": "delivery", + "value": "" + }, + { + "key": "file", + "value": "", + "type": "file" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/transformations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "transformations" + ] + }, + "description": "Apply OCR to scanned documents." + }, + "response": [] + }, + { + "name": "X HTML → PDF", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "convert" + }, + { + "key": "params", + "value": "{\"to\": \"pdf\"}" + }, + { + "key": "file", + "type": "file", + "src": "Analysis.html" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/conversions", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "conversions" + ] + }, + "description": "Upload an HTML file or URL JSON to convert to PDF. For remote HTML, set file content-type to application/vnd.gonitro.url+json with {\"url\": \"https://example.com\"}." + }, + "response": [] + }, + { + "name": "Deprecated - Linearize", + "protocolProfileBehavior": { + "followRedirects": true, + "disableUrlEncoding": false, + "disableCookies": false + }, + "request": { + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "method": "POST", + "header": [ + { + "key": "Authorization", + "value": "Bearer {{token}}" + }, + { + "key": "Content-Type", + "value": "multipart/form-data" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "method", + "value": "linearize" + }, + { + "key": "params", + "value": "{}" + }, + { + "key": "delivery", + "value": "" + }, + { + "key": "file", + "value": "", + "type": "file" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/transformations", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "transformations" + ] + }, + "description": "Deprecated / no longer supported. Included for reference." + }, + "response": [] + } + ], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "// Work in Progress folder: Validate status codes and response structure", + "pm.test(\"Status code is 200 or 201\", function () {", + " pm.expect(pm.response.code).to.be.oneOf([200, 201]);", + "});", + "pm.test(\"Response is an object\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData).to.be.an('object');", + "});" + ] + } + } + ] + } + ], + "event": [ + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "// Collection-level fallback tests for Nitro Automation Platform APIs", + "pm.test(\"Status code is 2xx\", function () {", + " pm.expect(pm.response.code).to.be.within(200, 299);", + "});", + "pm.test(\"Response is JSON or empty\", function () {", + " if(pm.response.text()) {", + " pm.expect(() => pm.response.json()).not.to.throw();", + " }", + "});" + ] + } + } + ] +} \ No newline at end of file diff --git a/postman/README.md b/postman/README.md new file mode 100644 index 0000000..8c647d0 --- /dev/null +++ b/postman/README.md @@ -0,0 +1,72 @@ +# Postman Collection + +This folder contains the Postman collection for the Nitro Platform API with examples for all major endpoints. + +## Getting Started + +### 1. Import the Collection + +1. Open Postman +2. Click **Import** in the top left +3. Select `Platform-API.postman_collection.json` +4. The collection will appear in your workspace + +### 2. Configure Environment Variables + +Create a new environment in Postman with these variables: + +| Postman Variable | Python .env Variable | Description | Example Value | +|------------------|---------------------|-------------|---------------| +| `baseUrl` | `PLATFORM_BASE_URL` | API base URL | `https://api.gonitro.dev` | +| `clientID` | `PLATFORM_CLIENT_ID` | Your client ID | `your-client-id` | +| `clientSecret` | `PLATFORM_CLIENT_SECRET` | Your client secret | `your-client-secret` | +| `token` | (auto-populated) | Bearer token | `eyJ0eXAiOiJKV1Q...` | + +**Note**: If you're also using the Python samples, you can use the same credential values from your `.env` file - just use the Postman variable names shown above. + +### 3. Get Authentication Token + +1. Navigate to **Authorization** → **Get Bearer Token** +2. Ensure your `clientID` and `clientSecret` are set +3. Send the POST request +4. The `token` variable will be automatically set for subsequent requests + +### 4. Run Sample Requests + +The collection is organized into folders: + +- **Authorization**: Get OAuth2 bearer tokens +- **Conversions**: Convert documents between formats +- **Extractions**: Extract text, form data, tables, and PII +- **Transformations**: Modify PDFs (compress, merge, split, etc.) +- **Jobs**: Check status and get results for async operations + +## Example Workflow + +1. **Get Token**: Run "Get Bearer Token" request +2. **Convert Document**: Use "Word → PDF" with a sample .docx file +3. **Extract Data**: Use "Extract PDF Text" on the converted PDF +4. **Transform**: Use "Compress" to reduce file size + +## File Upload + +Many endpoints require file uploads. In Postman: +1. Select **Body** → **form-data** +2. Set key to `file` (or as specified in the request) +3. Change type to **File** +4. Select your document + +## Async Operations + +Some operations return a job ID for async processing: +1. Submit the request and note the `jobId` in the response +2. Use **Jobs** → **Get Async Job Status** to check progress +3. When status is `completed`, use **Get Async Job Result** to download the result + +## Getting Your Credentials + +To get your API credentials: +1. Go to [https://admin.gonitro.com](https://admin.gonitro.com) +2. Navigate to **Settings** → **API** +3. Click **Create Application** +4. Name your application and save the Client ID and Client Secret diff --git a/power-automate/README.md b/power-automate/README.md new file mode 100644 index 0000000..1e66005 --- /dev/null +++ b/power-automate/README.md @@ -0,0 +1,89 @@ +# Power Automate Integration + +This folder contains instructions for creating a custom connector to integrate the Nitro Platform API with Microsoft Power Automate. + +## Creating Your Custom Connector + +### 1. Create New Custom Connector + +1. Go to [Power Automate](https://make.powerautomate.com) +2. Navigate to **Data** → **Custom connectors** +3. Click **New custom connector** → **Create from blank** +4. Name it "Nitro Platform API" + +### 2. Configure General Settings + +- **Description**: Document processing API for conversions, extractions, and transformations +- **Host**: `api.gonitro.dev` +- **Base URL**: `/` + +### 3. Configure Security + +1. Set **Authentication type** to **API Key** +2. **Parameter label**: API Key +3. **Parameter name**: `X-API-Key` +4. **Parameter location**: Header + +### 4. Add Key Operations + +Add these essential operations: + +#### Convert Document +- **Operation ID**: `convert-document` +- **Summary**: Convert Document +- **Verb**: POST +- **URL**: `/platform/conversions` +- **Request**: + - Body type: `multipart/form-data` + - Parameter: `file` (file upload) + - Parameter: `params` (string, JSON parameters) + +#### Extract Text +- **Operation ID**: `extract-text` +- **Summary**: Extract PDF Text +- **Verb**: POST +- **URL**: `/platform/extractions/pdf-text` +- **Request**: Body with `file` parameter + +#### Get Job Status +- **Operation ID**: `get-job-status` +- **Summary**: Get Job Status +- **Verb**: GET +- **URL**: `/jobs/{jobId}/status` +- **Parameter**: `jobId` (path parameter) + +### 5. Test Your Connector + +1. Go to **Test** tab +2. Create a new connection with your API key +3. Test the "Get Job Status" operation with a sample job ID + +## Sample Flows + +### Document Conversion Flow + +**Trigger**: When a file is added to SharePoint +1. **Get file content** from SharePoint +2. **Convert Document** using your custom connector +3. **Create file** in SharePoint with converted result + +### Batch Processing Flow + +**Trigger**: Scheduled (daily) +1. **List files** from SharePoint folder +2. **Apply to each** file: + - **Convert Document** + - **Get Job Status** (with delay/retry logic) + - **Get Job Result** when complete + - **Update file** in destination folder + +## Best Practices + +- **Error Handling**: Add try-catch blocks around API calls +- **Async Jobs**: Use "Do until" loops to poll job status +- **Rate Limits**: Add 1-2 second delays between API calls +- **File Size**: Check file size limits before processing + +## Authentication + +Get your API key from the Nitro platform dashboard and use it when creating connections to your custom connector. diff --git a/samples/python/.env.example b/samples/python/.env.example new file mode 100644 index 0000000..3a3d066 --- /dev/null +++ b/samples/python/.env.example @@ -0,0 +1,3 @@ +PLATFORM_BASE_URL=https://api.gonitro.dev +PLATFORM_CLIENT_ID=your-client-id-here +PLATFORM_CLIENT_SECRET=your-client-secret-here diff --git a/samples/python/README.md b/samples/python/README.md new file mode 100644 index 0000000..73f0bc4 --- /dev/null +++ b/samples/python/README.md @@ -0,0 +1,47 @@ +# Python Examples + +Python examples for integrating with the Nitro Platform API. + +## Setup + +1. Install dependencies: + ```bash + pip install -r requirements.txt + ``` + +2. Copy and configure environment variables: + ```bash + cp .env.example .env + # Edit .env with your credentials + ``` + +3. Run the quickstart example: + ```bash + python quickstart.py + ``` + +## Files + +- `quickstart.py` - Basic authentication and API call example +- `convert_document.py` - Document conversion example +- `async_job.py` - Async job processing example +- `requirements.txt` - Python dependencies +- `.env.example` - Environment variables template + +## Examples + +### Basic Authentication +```python +token = get_access_token(client_id, client_secret) +``` + +### Convert Document +```python +result = convert_document(token, file_path, output_format='pdf') +``` + +### Handle Async Jobs +```python +job_id = start_conversion_job(token, file_path) +result = poll_job_until_complete(token, job_id) +``` diff --git a/samples/python/quickstart.py b/samples/python/quickstart.py new file mode 100644 index 0000000..300d9b2 --- /dev/null +++ b/samples/python/quickstart.py @@ -0,0 +1,71 @@ +import os +import requests +from dotenv import load_dotenv + +load_dotenv() + +BASE_URL = os.getenv('PLATFORM_BASE_URL', 'https://api.gonitro.dev') +CLIENT_ID = os.getenv('PLATFORM_CLIENT_ID') +CLIENT_SECRET = os.getenv('PLATFORM_CLIENT_SECRET') + +def get_access_token(): + """Get OAuth2 access token using client credentials""" + url = f"{BASE_URL}/oauth/token" + data = { + "clientID": CLIENT_ID, + "clientSecret": CLIENT_SECRET + } + + response = requests.post(url, json=data) + response.raise_for_status() + return response.json()['accessToken'] + +def test_connection(token): + """Test API connection with a simple request""" + url = f"{BASE_URL}/jobs/test-job-id/status" + headers = {"Authorization": f"Bearer {token}"} + + try: + response = requests.get(url, headers=headers) + # 404 is expected for non-existent job, but proves auth works + if response.status_code == 404: + print("✅ Authentication successful (404 expected for test job ID)") + return True + response.raise_for_status() + return True + except requests.exceptions.HTTPError as e: + if e.response.status_code == 404: + print("✅ Authentication successful (404 expected for test job ID)") + return True + raise + +def main(): + if not CLIENT_ID or not CLIENT_SECRET: + print("❌ Missing credentials!") + print("To get your credentials:") + print("1. Go to https://admin.gonitro.com") + print("2. Navigate to Settings → API") + print("3. Click 'Create Application'") + print("4. Name your application and save the Client ID and Client Secret") + print("5. Set environment variables:") + print(" export PLATFORM_CLIENT_ID=") + print(" export PLATFORM_CLIENT_SECRET=") + return + + try: + print("🔐 Getting access token...") + token = get_access_token() + print("✅ Token obtained successfully") + + print("🧪 Testing API connection...") + test_connection(token) + print("✅ API connection successful") + + print("\n🎉 Setup complete! You can now use the Platform API.") + print("📖 See https://developers.gonitro.com/docs for API documentation") + + except Exception as e: + print(f"❌ Error: {e}") + +if __name__ == "__main__": + main() diff --git a/samples/python/requirements.txt b/samples/python/requirements.txt new file mode 100644 index 0000000..2b1be2a --- /dev/null +++ b/samples/python/requirements.txt @@ -0,0 +1,2 @@ +requests>=2.31.0 +python-dotenv>=1.0.0 From 566e738c9ac7da43889672c0cafcfaf91b5c40c6 Mon Sep 17 00:00:00 2001 From: Ronan Harris Date: Thu, 27 Nov 2025 14:13:52 +0000 Subject: [PATCH 2/2] gitignore again --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 74b28a0..bd5f1b8 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,11 @@ __pycache__/ # OS .DS_Store +# IDE +.vscode/ +.idea/ +*.swp +*.swo # API keys and secrets *secret* *key*