openapi: 3.0.3 info: title: 'PUDO API – Developer Documentation' description: 'A standalone Pick Up Drop Off (PUDO) platform integration API. Connect your courier, e-commerce, or logistics system directly to our network of local drop-off points.' version: 1.0.0 servers: - url: 'https://pudo.2pointapp.com' tags: - name: 'PUDO Points' description: '' - name: Packages description: '' - name: Webhooks description: '' components: securitySchemes: default: type: apiKey name: X-PUDO-Key in: header description: 'You can retrieve your token by visiting your dashboard and clicking Generate API token.' security: - default: [] paths: /api/v1/pudo-points/all: get: summary: 'List All PUDO points' operationId: listAllPUDOPoints description: 'Find all active PUDO points. Use query parameters to filter by branch or cold storage availability.' parameters: - in: query name: branch_ref description: 'Filter by branch reference.' example: accra-main required: false schema: type: string description: 'Filter by branch reference.' example: accra-main - in: query name: cold_storage description: 'Filter by cold storage availability.' example: true required: false schema: type: boolean description: 'Filter by cold storage availability.' example: true - in: header name: X-PUDO-Key description: '' example: '{YOUR_AUTH_KEY}' schema: type: string - in: header name: X-PUDO-Timestamp description: '' example: 'required Current Unix timestamp in seconds. Example: 1709845200' schema: type: string - in: header name: X-PUDO-Signature description: '' example: 'required HMAC-SHA256(timestamp + raw_body, api_secret). Example: a3f5c2...' schema: type: string responses: 200: description: '' content: text/plain: schema: type: string example: "{\n \"status\": \"success\",\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Shell Station East Legon\",\n \"address\": \"Boundary Road, Accra\",\n \"lat\": \"5.63410000\",\n \"lng\": \"-0.15230000\",\n \"has_cold_storage\": true,\n \"currency\": \"GHS\",\n \"price\": 5.00,\n \"operating_hours\": {\n \"mon\": \"08:00-20:00\",\n \"tue\": \"08:00-20:00\",\n }\n }\n]" tags: - 'PUDO Points' /api/v1/pudo-points: get: summary: 'List Nearby PUDO points' operationId: listNearbyPUDOPoints description: 'Find active PUDO points near a location or within a branch.' parameters: - in: query name: lat description: 'Latitude of the search center.' example: 5.6037 required: false schema: type: number description: 'Latitude of the search center.' example: 5.6037 - in: query name: lng description: 'Longitude of the search center.' example: -0.187 required: false schema: type: number description: 'Longitude of the search center.' example: -0.187 - in: query name: radius description: 'Search radius in KM. Default: 10.' example: 25 required: false schema: type: integer description: 'Search radius in KM. Default: 10.' example: 25 - in: query name: branch_ref description: 'Filter by branch reference.' example: accra-main required: false schema: type: string description: 'Filter by branch reference.' example: accra-main - in: query name: cold_storage description: 'Filter by cold storage availability.' example: true required: false schema: type: boolean description: 'Filter by cold storage availability.' example: true - in: header name: X-PUDO-Key description: '' example: '{YOUR_AUTH_KEY}' schema: type: string - in: header name: X-PUDO-Timestamp description: '' example: 'required Current Unix timestamp in seconds. Example: 1709845200' schema: type: string - in: header name: X-PUDO-Signature description: '' example: 'required HMAC-SHA256(timestamp + raw_body, api_secret). Example: a3f5c2...' schema: type: string responses: 200: description: '' content: text/plain: schema: type: string example: "{\n \"status\": \"success\",\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Shell Station East Legon\",\n \"address\": \"Boundary Road, Accra\",\n \"lat\": \"5.63410000\",\n \"lng\": \"-0.15230000\",\n \"distance\": 2.4,\n \"has_cold_storage\": true\n \"currency\": \"GHS\",\n \"price\": 5.00\n }\n ]\n}" tags: - 'PUDO Points' '/api/v1/pudo-points/{id}': get: summary: 'Get PUDO point details' operationId: getPUDOPointDetails description: '' parameters: - in: header name: X-PUDO-Key description: '' example: '{YOUR_AUTH_KEY}' schema: type: string - in: header name: X-PUDO-Timestamp description: '' example: 'required Current Unix timestamp in seconds. Example: 1709845200' schema: type: string - in: header name: X-PUDO-Signature description: '' example: 'required HMAC-SHA256(timestamp + raw_body, api_secret). Example: a3f5c2...' schema: type: string responses: 401: description: '' content: application/json: schema: type: object example: message: 'Invalid API key' properties: message: type: string example: 'Invalid API key' tags: - 'PUDO Points' parameters: - in: path name: id description: 'The ID of the PUDO point.' example: 1 required: true schema: type: integer /api/v1/packages: get: summary: 'List packages' operationId: listPackages description: 'Retrieve packages that have been ingested into the PUDO system by your integration.' parameters: - in: query name: status description: 'Filter by package status (e.g., pending, dropped, ready, picked_up).' example: ready required: false schema: type: string description: 'Filter by package status (e.g., pending, dropped, ready, picked_up).' example: ready - in: query name: limit description: 'Limit the number of results. Default: 15.' example: 10 required: false schema: type: integer description: 'Limit the number of results. Default: 15.' example: 10 - in: header name: X-PUDO-Key description: '' example: '{YOUR_AUTH_KEY}' schema: type: string - in: header name: X-PUDO-Timestamp description: '' example: 'required Current Unix timestamp in seconds. Example: 1709845200' schema: type: string - in: header name: X-PUDO-Signature description: '' example: 'required HMAC-SHA256(timestamp + raw_body, api_secret). Example: a3f5c2...' schema: type: string responses: 200: description: '' content: application/json: schema: type: object example: status: success data: current_page: 1 data: - id: 1 tracking_number: PUDO-12345678 external_booking_ref: BK-9921 pudo_point_id: 1 customer_name: 'John Doe' status: pending payment_status: unpaid created_at: '2024-03-08T10:00:00.000000Z' total: 1 properties: status: type: string example: success data: type: object properties: current_page: type: integer example: 1 data: type: array example: - id: 1 tracking_number: PUDO-12345678 external_booking_ref: BK-9921 pudo_point_id: 1 customer_name: 'John Doe' status: pending payment_status: unpaid created_at: '2024-03-08T10:00:00.000000Z' items: type: object properties: id: type: integer example: 1 tracking_number: type: string example: PUDO-12345678 external_booking_ref: type: string example: BK-9921 pudo_point_id: type: integer example: 1 customer_name: type: string example: 'John Doe' status: type: string example: pending payment_status: type: string example: unpaid created_at: type: string example: '2024-03-08T10:00:00.000000Z' total: type: integer example: 1 tags: - Packages '/api/v1/packages/{tracking_number}': get: summary: 'Get package details' operationId: getPackageDetails description: 'Retrieve the details and statuses for a specific package using its tracking number.' parameters: - in: header name: X-PUDO-Key description: '' example: '{YOUR_AUTH_KEY}' schema: type: string - in: header name: X-PUDO-Timestamp description: '' example: 'required Current Unix timestamp in seconds. Example: 1709845200' schema: type: string - in: header name: X-PUDO-Signature description: '' example: 'required HMAC-SHA256(timestamp + raw_body, api_secret). Example: a3f5c2...' schema: type: string responses: 200: description: '' content: application/json: schema: type: object example: status: success data: id: 1 tracking_number: PUDO-12345678 external_booking_ref: BK-9921 pudo_point_id: 1 customer_name: 'John Doe' status: pending payment_status: unpaid created_at: '2024-03-08T10:00:00.000000Z' properties: status: type: string example: success data: type: object properties: id: type: integer example: 1 tracking_number: type: string example: PUDO-12345678 external_booking_ref: type: string example: BK-9921 pudo_point_id: type: integer example: 1 customer_name: type: string example: 'John Doe' status: type: string example: pending payment_status: type: string example: unpaid created_at: type: string example: '2024-03-08T10:00:00.000000Z' 404: description: '' content: application/json: schema: type: object example: status: error message: 'Package not found.' properties: status: type: string example: error message: type: string example: 'Package not found.' tags: - Packages parameters: - in: path name: tracking_number description: 'The PUDO tracking number of the package.' example: PUDO-12345678 required: true schema: type: string /api/v1/packages/ingest: post: summary: 'Ingest a new package' operationId: ingestANewPackage description: "Submit a package from your system to a PUDO point.\nThe package will start in 'pending' status." parameters: - in: header name: X-PUDO-Key description: '' example: '{YOUR_AUTH_KEY}' schema: type: string - in: header name: X-PUDO-Timestamp description: '' example: 'required Current Unix timestamp in seconds. Example: 1709845200' schema: type: string - in: header name: X-PUDO-Signature description: '' example: 'required HMAC-SHA256(timestamp + raw_body, api_secret). Example: a3f5c2...' schema: type: string responses: 200: description: '' content: application/json: schema: type: object example: status: success message: 'Package ingested successfully' data: tracking_number: PUDO-12345678 status: pending properties: status: type: string example: success message: type: string example: 'Package ingested successfully' data: type: object properties: tracking_number: type: string example: PUDO-12345678 status: type: string example: pending tags: - Packages requestBody: required: true content: application/json: schema: type: object properties: pudo_point_id: type: integer description: 'ID of the PUDO point.' example: 1 external_booking_ref: type: string description: "Your system's reference ID." example: BK-9921 customer_name: type: string description: 'Full name of the recipient.' example: 'John Doe' customer_email: type: string description: 'Email for notifications.' example: john@example.com customer_phone: type: string description: 'Phone for notification.' example: '+233240000000' cold_storage: type: boolean description: 'If the package requires refrigeration.' example: false notes: type: string description: 'optional Extra instructions.' example: 'Fragile electronics' nullable: true payment_status: type: string description: "optional The payment status, e.g. 'paid' or 'unpaid'." example: unpaid nullable: true payment_method: type: string description: "optional The payment method, e.g. 'cod'." example: cod nullable: true amount_to_collect: type: decimal description: 'optional The amount to collect from the customer if unpaid.' example: '15.50' nullable: true required: - pudo_point_id - external_booking_ref - customer_name - customer_email - customer_phone - cold_storage /api/v1/webhooks/register: post: summary: 'Register Webhook' operationId: registerWebhook description: "Register a URL to receive status updates when a package status changes.\nWe will POST to this URL with an HMAC signature." parameters: - in: header name: X-PUDO-Key description: '' example: '{YOUR_AUTH_KEY}' schema: type: string - in: header name: X-PUDO-Timestamp description: '' example: 'required Current Unix timestamp in seconds. Example: 1709845200' schema: type: string - in: header name: X-PUDO-Signature description: '' example: 'required HMAC-SHA256(timestamp + raw_body, api_secret). Example: a3f5c2...' schema: type: string responses: 200: description: '' content: application/json: schema: type: object example: status: success message: 'Webhook registered successfully' data: webhook_url: 'https://api.mycompany.com/pudo/webhook' properties: status: type: string example: success message: type: string example: 'Webhook registered successfully' data: type: object properties: webhook_url: type: string example: 'https://api.mycompany.com/pudo/webhook' tags: - Webhooks requestBody: required: true content: application/json: schema: type: object properties: webhook_url: type: url description: 'The callback URL.' example: 'https://api.mycompany.com/pudo/webhook' required: - webhook_url /api/v1/webhooks/logistics/status: post: summary: 'Handle incoming status webhooks from 2PointLogistics.' operationId: handleIncomingStatusWebhooksFrom2PointLogistics description: '' parameters: - in: header name: X-PUDO-Key description: '' example: '{YOUR_AUTH_KEY}' schema: type: string - in: header name: X-PUDO-Timestamp description: '' example: 'required Current Unix timestamp in seconds. Example: 1709845200' schema: type: string - in: header name: X-PUDO-Signature description: '' example: 'required HMAC-SHA256(timestamp + raw_body, api_secret). Example: a3f5c2...' schema: type: string responses: { } tags: - Webhooks requestBody: required: true content: application/json: schema: type: object properties: event: type: string description: '' example: architecto tracking_number: type: string description: '' example: architecto status: type: string description: 'Logistics UUID.' example: architecto eta_to_pickup_minutes: type: integer description: '' example: 16 nullable: true eta_to_dropoff_minutes: type: integer description: '' example: 16 nullable: true required: - event - tracking_number - status