# Fliinow Partner API - Complete Technical Documentation > Comprehensive API documentation for OTA partners integrating travel financing via the Fliinow Partner REST API. --- ## 1. Introduction Fliinow is a travel financing platform that enables Online Travel Agencies (OTAs) to offer installment payment options to their customers. The Fliinow Partner API provides a RESTful interface for creating financing operations, retrieving available payment plans, and managing the complete financing lifecycle. ### Key Features - **Fast Integration**: First operation in less than 5 minutes - **Multi-Provider**: Automatic fallback between multiple finance providers - **Secure**: API Key authentication, HTTPS required - **Conversion Boost**: Enable customers who can't pay upfront --- ## 2. Authentication ### API Keys All requests require the `X-Fliinow-API-Key` header. You'll receive two keys: - **Sandbox Key**: Prefix `fk_test_` - For testing and development - **Production Key**: Prefix `fk_live_` - For live operations ### API Key Types There are two types of API key, and the type determines the headers required on every request: - **Agency key**: linked to a single agency. Only `X-Fliinow-API-Key` is required. - **Management group key**: can act on behalf of any active agency of the group. Every request must also include the `X-Fliinow-Agency` header with the id of the target agency. The ONLY exception is `GET /agencies`, which requires no `X-Fliinow-Agency` and returns the valid agency ids for that header. Recommended flow with a management group key: 1. `GET /agencies` (no `X-Fliinow-Agency`) to discover the group's agencies. 2. Send every other request with `X-Fliinow-Agency: `. ### Environments | Environment | Base URL | Purpose | |-------------|----------|---------| | Sandbox | https://demo.fliinow.com/integration-api/v1 | Testing and development | | Production | https://app.fliinow.com/integration-api/v1 | Live operations | ### Example Request ```http GET /operations/12345/status HTTP/1.1 Host: demo.fliinow.com X-Fliinow-API-Key: fk_test_your_api_key_here Content-Type: application/json ``` ### Security Warning Never expose your API Key in frontend code. All API calls must be made from your server. --- ## 3. API Endpoints ### 3.0 Health Check **GET /health** Returns API health status, current version, server timestamp, and your partner code. Useful for connectivity testing and monitoring. #### Response ```json { "status": "ok", "version": "1.5.0", "timestamp": "2026-01-31T12:00:00Z", "partnerCode": "YOUR_PARTNER_CODE" } ``` #### Use Cases - Verify API connectivity before starting integration - Monitor API availability from your systems - Check if your API key is valid - Synchronize timestamps between systems ### 3.1 Create Operation **POST /operations** Creates the client and the financing operation in a single request. At least one flight, hotel or service is required. #### Request Body ```json { "externalId": "YOUR-BOOKING-123", "packageName": "Cancun All Inclusive", "packageTravel": true, "travelersNumber": 2, "totalPrice": 1500.00, "successRedirectUrl": "https://yoursite.com/booking/success", "errorRedirectUrl": "https://yoursite.com/booking/error", "webhookUrl": "https://yoursite.com/webhooks/fliinow", "client": { "firstName": "Juan", "lastName": "García Tomás", "email": "juan@example.com", "prefix": "+34", "phone": "612345678", "documentId": "12345678A", "documentValidityDate": "31-12-2030", "gender": "MALE", "birthDate": "15-06-1985", "nationality": "ESP", "address": "Calle Mayor 1", "city": "Madrid", "postalCode": "28001", "countryCode": "ESP" }, "flights": [], "hotels": [], "services": [] } ``` Notes: `packageTravel` and `travelersNumber` are required. Dates use dd-MM-yyyy. `countryCode` and `nationality` are 3-letter ISO codes. `successRedirectUrl`, `errorRedirectUrl` and `webhookUrl` are optional. #### Response (201 Created) ```json { "id": "op-a0b1c2d4", "operationNumber": 513, "externalId": "YOUR-BOOKING-123", "status": "GENERATED", "totalPrice": { "amount": 1500.00, "currency": "EUR" }, "totalReserve": { "amount": 1545.00, "currency": "EUR" }, "financingUrl": "https://demo.fliinow.com/financing/pay?o=op-a0b1c2d4&t=a8a12428-8dd9-4b26-9d61-d9449de30f67" } ``` The endpoint is idempotent per `externalId`: repeating the request with the same `externalId` returns the existing operation. ### 3.2 Simulate Financing **GET /financing/simulate/{totalPrice}** Simulates the financing offers available for an amount, without creating an operation. #### Response (200 OK) ```json { "currency": "EUR", "financialOffers": [ { "id": 1, "companyName": "COFIDIS", "tae": 12.45, "tin": 11.95, "installments": 12, "commonQuota": 95.42, "differentialQuota": 95.30, "differentialIsFirst": false, "totalInterestPaid": 45.04, "totalFinanced": 1145.04 } ] } ``` Errors: 400 VALIDATION_ERROR (invalid amount), 422 NO_FINANCIAL_COMPANIES_CONFIGURED. ### 3.3 Get Financing Details **GET /financing/{operationIdentifier}** Retrieves the eligible financing offers for an existing operation. Same response shape as the simulation, but restricted to the offers the operation is actually eligible for. Use the offer `id` in POST /financing. Errors: 404 OPERATION_NOT_FOUND, 422 NOT_ELIGIBLE_FOR_FINANCING. ### 3.4 Start Financing **POST /financing** Starts the financing process for an operation with the customer's selected offer. #### Request Body ```json { "operationIdentifier": "op-a0b1c2d4", "financialOfferId": 1 } ``` #### Response (200 OK · REQUESTED) ```json { "paymentUrl": "https://checkout.provider.com/financing/xyz789", "financingStatus": "REQUESTED" } ``` Redirect the customer to `paymentUrl` to complete the provider checkout. #### Response (200 OK · REFUSED / ERROR) ```json { "paymentUrl": null, "financingStatus": "REFUSED", "hasAlternativeFinancialOffers": true } ``` If `hasAlternativeFinancialOffers` is true, fetch GET /financing/{operationIdentifier} again and offer another option. Errors: 400 VALIDATION_ERROR, 409 NOT_ACTIVE_OPERATION, 422 NOT_ELIGIBLE_FINANCIAL_OFFER. ### 3.5 Check Status **GET /operations/{operationIdentifier}/status** Returns the current status of an operation. Always verify status after callback. #### HTTP Caching This endpoint supports ETag-based caching: - **ETag Header**: Format `"{status}-{updatedAtEpoch}"` - **Cache-Control**: `max-age=60, must-revalidate` - **If-None-Match**: Include previous ETag to receive 304 Not Modified if unchanged #### Response ```json { "operationId": "op_abc123", "status": "FAVORABLE", "updatedAt": "2026-01-15T10:30:00Z" } ``` #### Response Headers ``` ETag: "FAVORABLE-1706789012" Cache-Control: max-age=60, must-revalidate ``` #### 304 Not Modified When `If-None-Match` header matches current ETag, returns 304 with no body. ### 3.6 List Operations **GET /operations** Lists all operations with pagination and optional filters. #### Query Parameters | Parameter | Type | Description | |-----------|------|-------------| | page | integer | Page number (from 0) | | size | integer | Operations per page (max 100) | | status | string | Filter by status (optional) | | from | date | Date from yyyy-MM-dd (optional) | | to | date | Date to yyyy-MM-dd (optional) | ### 3.7 Cancel Operation **POST /operations/{id}/cancel** Cancels an operation the customer has not signed yet. Valid for GENERATED, PENDING and ERROR; the operation is left CANCELLED. No finance provider is contacted and no money moves. CLIENT_REQUESTED cannot be cancelled — its request is already live at the provider, so it can only end up confirmed, refused or refunded. A CONFIRMED operation must be refunded instead. Both cases return 400 `OPERATION_NOT_CANCELLABLE` with the current status in `additionalInfo.operationStatus`. #### Request Body (optional) | Field | Type | Required | Description | |-------|------|----------|-------------| | reason | string | No | Why it is being cancelled (max 255 chars). Kept in the operation history. | ### 3.7.1 Get Refund Breakdown **GET /operations/{id}/refund/details** Returns what the customer would get back if a CONFIRMED operation were refunded right now. #### Response (200 OK) ```json { "operationId": "op00000123", "totalReserve": { "amount": 306.00, "currency": "EUR" }, "managementFees": { "amount": 6.00, "currency": "EUR" }, "fliinowCancellationFee": { "amount": 1.50, "currency": "EUR" }, "fliinowCancellationFeePercentage": 0.50, "totalToRefund": { "amount": 298.50, "currency": "EUR" } } ``` `totalToRefund` already discounts the non-refundable fees charged on the operation and Fliinow's cancellation fee. Any charge you send when refunding lowers it by the same value. Returns 400 `OPERATION_NOT_REFUNDABLE` if the operation is not CONFIRMED. ### 3.7.2 Refund Operation **POST /operations/{id}/refund** Refunds a CONFIRMED operation through its finance provider, records the cancellation charges in the monthly invoice and leaves the operation REFUNDED. #### Request Body (optional) | Field | Type | Required | Description | |-------|------|----------|-------------| | agencyCancellationFee | number | No | Charge kept by the agency. Defaults to 0. | | providerCancellationFee | number | No | Charge kept by the travel provider. Defaults to 0. | | reason | string | No | Why it is being refunded (max 255 chars). Kept in the operation history. | Returns 400 `OPERATION_NOT_REFUNDABLE` if the operation is not CONFIRMED, and 422 `OPERATION_NOT_REFUNDABLE` if the finance provider rejects the refund — in that case nothing changes: no status change and no charges recorded. ### 3.8 Get Operation by External ID **GET /operations/by-external-id/{externalId}** Retrieves an operation using your external reference ID (the `externalId` you provided when creating the operation). #### Path Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | externalId | string | Yes | Your external reference ID for the operation | #### Response (200 OK) ```json { "id": "op-a0b1c2d4", "externalId": "BOOKING-12345", "status": "GENERATED", "financingUrl": "https://app.fliinow.com/financing/pay?o=op-a0b1c2d4&t=a8a12428-8dd9-4b26-9d61-d9449de30f67", "totalPrice": { "amount": 1500.00, "currency": "EUR" }, "totalReserve": { "amount": 1545.00, "currency": "EUR" } } ``` #### Use Cases - Look up operations using your internal booking reference - Sync operation status with your booking system - Avoid storing Fliinow operation IDs in your database --- ### 3.9 List Group Agencies **GET /agencies** Management group keys only: returns the active agencies of the group your API key can act on behalf of, sorted by id. This is the ONLY endpoint that does not require the `X-Fliinow-Agency` header — the returned ids are the valid values for that header on every other endpoint. #### Response (200 OK) ```json [ { "id": 41, "tradeName": "Viajes Luna Azul", "address": "Calle de la Estrella 42", "postalCode": "28004", "city": "Madrid", "countryCode": "ESP" } ] ``` #### Use Cases - Discover the agency ids valid for the `X-Fliinow-Agency` header - List the agencies of your group without out-of-band configuration ### 3.10 Acknowledge Webhook Event **PUT /operations/webhook-events/ack** If you provide a `webhookUrl` when creating an operation, Fliinow sends a POST to it whenever the operation reaches a final or actionable status (CONFIRMED, REFUSED, EXPIRED, CANCELLED, REFUNDED, ERROR — intermediate statuses such as PENDING are not notified). The notification body carries three fields: ```json { "operationIdentifier": "op-a0b1c2d4", "operationStatus": "CONFIRMED", "eventId": 42 } ``` To confirm you received and processed the event, send the SAME payload back via this endpoint. Unacknowledged events may be redelivered. #### Request Body ```json { "operationIdentifier": "op-a0b1c2d4", "operationStatus": "CONFIRMED", "eventId": 42 } ``` #### Responses - 200 OK: event acknowledged - 403 OPERATION_ACCESS_DENIED / WEBHOOK_EVENT_OPERATION_MISMATCH - 404 OPERATION_NOT_FOUND / WEBHOOK_EVENT_NOT_FOUND - 409 WEBHOOK_EVENT_STATUS_MISMATCH / WEBHOOK_EVENT_NOT_ACKNOWLEDGEABLE For management group keys, include the `X-Fliinow-Agency` header with the id of the agency that owns the operation. --- ## 4. Operation Statuses | Status | Description | Recommended Action | |--------|-------------|-------------------| | GENERATED | Operation created, pending financing initiation | Show plans and wait for customer selection | | PENDING | Financing process started | Wait for customer to complete checkout | | CLIENT_REQUESTED | Customer selected a financing option | Wait for provider response | | PENDING_RESPONSE | Waiting for provider decision | Poll status periodically | | FAVORABLE | Provider approved the financing | ✅ Confirm booking, issue trip | | CONFIRMED | Financing confirmed and active | Trip confirmed, process complete | | REFUSED | All providers rejected the customer | ❌ Offer alternative payment method | | REFUNDED | Confirmed operation refunded through the provider | Archive operation | | CANCELLED | Cancelled before the customer signed it | Create a new operation if the customer wants to retry | | EXPIRED | Time limit exceeded without completion | Create new operation if customer wants to retry | | ERROR | Technical error occurred | Contact support or retry | --- ## 5. Integration Flows ### 5.1 Standard Flow (Recommended) The simplest integration requiring only 2 API calls: 0. **Health Check** (GET /health) - Optional but recommended - Verify API connectivity before starting - Get current API version and server timestamp 1. **Create Operation** (POST /operations) - Send customer and travel data - Optionally include `successRedirectUrl` and `errorRedirectUrl` to redirect customers to your URLs, and `webhookUrl` to be notified of status changes - Receive `financingUrl` 2. **Redirect to Fliinow** - Customer goes to financingUrl - Fliinow shows available plans - Customer selects plan - Automatic redirect to provider checkout 3. **Provider Checkout** - Customer completes signing process 4. **Redirect back** - Customer returns to your `successRedirectUrl` or `errorRedirectUrl` (if provided in POST /operations) - Otherwise, redirected to Fliinow default URLs 5. **Verify Status** (GET /operations/{operationIdentifier}/status) - Always confirm actual status before issuing trip - Or wait for the webhook notification and acknowledge it (PUT /operations/webhook-events/ack) 6. **Sync with Booking System** (GET /operations/by-external-id/{externalId}) - Optional - Use your internal booking reference to look up operations - No need to store Fliinow operation IDs ### 5.2 Advanced Flow (Optional) For partners who want to display financing offers on their own website: 1. **Create Operation** (POST /operations) 2. **Get Financing Details** (GET /financing/{operationIdentifier}) - Display the eligible offers on your site 3. **Customer Selects an Offer** - On your frontend 4. **Start Financing** (POST /financing with operationIdentifier + financialOfferId) - Get the provider checkout `paymentUrl` 5. **Redirect to Provider** 6. **Redirect back** 7. **Verify Status** (GET /operations/{operationIdentifier}/status) or wait for the webhook ### Multi-Funding If the selected provider rejects the customer, Fliinow automatically tries other providers offering the same installment count. No extra implementation needed. --- ## 6. Error Handling ### HTTP Error Codes | Code | Name | Description | Action | |------|------|-------------|--------| | 400 | Bad Request | Invalid or missing data | Review request body | | 401 | Unauthorized | Invalid or missing API Key | Verify X-Fliinow-API-Key header | | 403 | Forbidden | No permission for this operation | Verify operation belongs to your account | | 404 | Not Found | Operation not found | Verify operation ID | | 409 | Conflict | Operation not in valid state | Check current status before action | | 429 | Too Many Requests | Rate limit exceeded | Implement rate limiting | | 500 | Internal Server Error | Fliinow internal error | Retry with exponential backoff | ### Error Response Format ```json { "error": "BAD_REQUEST", "message": "Field 'email' is required", "timestamp": "2024-01-15T10:30:00Z" } ``` --- ## 7. Best Practices ### Security - Store API Key in environment variables, never in code - Make all calls from backend, never from frontend - Use HTTPS for callback URLs ### Connectivity & Monitoring - Use GET /health on application startup to verify API connectivity - Implement periodic health checks to monitor API availability - Compare server timestamp to detect clock drift issues ### Operation Management - Use externalId consistently when creating operations - Use GET /operations/by-external-id/{externalId} to sync with your booking system - Consider externalId as your primary reference (no need to store Fliinow IDs) ### Robustness - Always verify status with GET /status after callback - Implement retries with exponential backoff for 5xx errors - Handle all HTTP error codes - Store accessToken for future reference ### User Experience - Clearly show APR and total amount to pay - Indicate redirect is to a secure site - Have friendly error page for rejections ### Data Formatting - Use externalId that links to your booking system - Dates in body: dd-MM-yyyy format - Dates in query params: yyyy-MM-dd format --- ## 8. Go-Live Checklist Before switching to production: - [ ] Full integration tested in Sandbox - [ ] All statuses handled (FAVORABLE, REFUSED, REFUNDED, CANCELLED, EXPIRED, ERROR) - [ ] Callbacks working correctly - [ ] Status verification implemented - [ ] Robust error handling - [ ] Production API Key configured - [ ] Callback URLs pointing to production ### Switching to Production Only two changes needed: 1. **Base URL**: demo.fliinow.com → app.fliinow.com 2. **API Key**: fk_test_... → fk_live_... --- ## 9. SDK A TypeScript/JavaScript SDK is available for easier integration: **Package**: `@fliinow-com/fliinow-partner-api` - npm: https://www.npmjs.com/package/@fliinow-com/fliinow-partner-api - GitHub: https://github.com/fliinow-com/fliinow-partner-api --- ## 10. Support ### Technical Support - Email: support@fliinow.com - Response time: < 24h business hours ### Urgent Issues - Email: support@fliinow.com - Response time: < 2h --- ## Resources - Main Site: https://fliinow.com - Marketplace: https://marketplace.fliinow.com - Simulator: https://simulador.fliinow.com - API Documentation: https://docs.fliinow.com