| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Contacts (contacts)
• Sales (sale_management) • Discuss (mail) • Invoicing (account) |
| Lines of code | 1914 |
| Technical Name |
odoo_rest_api_gateway |
| License | LGPL-3 |
| Website | http://auraodoo.tech/ |
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Contacts (contacts)
• Sales (sale_management) • Discuss (mail) • Invoicing (account) |
| Lines of code | 1914 |
| Technical Name |
odoo_rest_api_gateway |
| License | LGPL-3 |
| Website | http://auraodoo.tech/ |
REST API Gateway Pro
Odoo 19 Production-Ready REST API with JWT, Rate Limiting & Analytics
Watch Demo
Module Overview
JWT Authentication
Secure token-based authentication with access and refresh tokens. Tokens expire automatically.
SecurityAPI Key Management
Per-application keys with scope-based permissions and rate limiting controls.
AuthorizationRate Limiting
Per-minute and per-hour throttling with automatic IP blocking on violations.
ProtectionComplete Workflow
API Request Flow
-
Client Request
Client sends HTTP request with JWT token or API key
-
Middleware Processing
Request passes through api_middleware.py for authentication and validation
-
Authorization Check
Verify scope permissions (products_read, products_write, etc.)
-
Rate Limit Check
Check per-minute and per-hour limits for the API key
-
IP Whitelist Validation
Verify request IP against allowed IPs if configured
-
Controller Processing
Route to appropriate controller (product, order, customer)
-
Business Logic Execution
Execute create, read, update, or delete operations
-
Response Formatting
Serialize data using field whitelist for security
-
Request Logging
Save request/response info to api.log model for audit trail
-
JSON Response
Return formatted JSON with success/error status
Authentication Methods
| Method | Header | Format | Scope |
|---|---|---|---|
| JWT Token | Authorization | Bearer <access_token> | All capabilities |
| API Key | X-API-Key | <api_key> | By configuration |
Create Operations
Create Product
Endpoint Details
Method: POST
Path: /api/v1/products
Scope Required: products_write
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name |
String | Yes | Product name/title |
default_code |
String | No | Internal product code/SKU |
barcode |
String | No | Product barcode |
list_price |
Float | No | Selling price |
standard_price |
Float | No | Cost price |
categ_id |
Integer | No | Category ID |
type |
String | No | consu, product, service |
description_sale |
String | No | Product description |
Processing Steps
- Validate JSON body format
- Check required fields (name)
- Filter writable fields from request
- Create product.template record in database
- Serialize response using PRODUCT_FIELDS whitelist
- Log request to api.log
- Return JSON response with created product data
Response
{
"success": true,
"data": {
"id": 1,
"name": "Example Product",
"default_code": "PROD001",
"list_price": 99.99,
"categ_id": {"id": 1, "name": "Electronics"},
"active": true
},
"message": "Product created successfully"
}
Create Order
Endpoint Details
Method: POST
Path: /api/v1/orders
Scope Required: orders_write
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
partner_id |
Integer | Yes | Customer ID (res.partner) |
order_lines |
Array | Yes | Array of order line objects |
warehouse_id |
Integer | No | Default warehouse used |
notes |
String | No | Order notes/comments |
Order Line Structure
"order_lines": [
{
"product_id": 1,
"product_qty": 5,
"price_unit": 99.99
}
]
Processing Steps
- Parse JSON request body
- Validate partner_id exists
- Validate order_lines array
- Validate each product exists
- Create sale.order record
- Create sale.order.line records for each line
- Calculate totals and tax
- Return order data with confirmation status
Create Customer
Endpoint Details
Method: POST
Path: /api/v1/customers
Scope Required: customers_write
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name |
String | Yes | Customer name |
email |
String | No | Email address |
phone |
String | No | Phone number |
street |
String | No | Address |
country_id |
Integer | No | Country ID |
is_company |
Boolean | No | Mark as company |
Processing Steps
- Validate JSON body
- Check required name field
- Filter writable fields
- Create res.partner record
- Validate email format if provided
- Serialize response data
- Log to audit trail
- Return created customer record
Authentication System
JWT Token Flow
Token Generation
-
User Login
POST /api/v1/auth/login with email/password -
Credential Validation
Verify user exists and password matches -
Token Creation
Access token (1 hour) and refresh token (7 days) generated via PyJWT -
Payload Encoding
Include user ID, token type, iat, and exp claims -
Token Response
Return both tokens to client for storage
Token Validation on Request
- Extract token from Authorization header
- Decode JWT with secret key
- Verify token type (access vs refresh)
- Check expiration timestamp
- Extract user ID from payload
- Grant access if valid
Token Configuration
| Algorithm | HS256 |
| Access Token TTL | 3600 seconds (1 hour) |
| Refresh Token TTL | 604800 seconds (7 days) |
| Secret Source | Database UUID + odoo-rest-api prefix |
API Key Authentication
Key Lifecycle
-
Key Generation
Auto-generated 64-character URL-safe token on creation -
Key Hashing
SHA-256 hash stored in database for security -
Scope Assignment
Assign permissions (products_read, products_write, etc.) -
Rate Limiting
Configure per-minute and per-hour limits -
IP Whitelist
Optionally restrict to specific IP addresses -
Expiration Date
Optional expiration for temporary keys
Key Validation Process
- Extract API key from X-API-Key header
- Compute SHA-256 hash of provided key
- Search for matching key record
- Check key is active (not revoked)
- Validate expiration date
- Load associated user and scopes
- Grant or deny access based on scopes
Usage Examples
Example 1: Create Product with JWT
Request
curl -X POST http://localhost:8069/api/v1/products \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"name": "Wireless Keyboard",
"default_code": "KB001",
"list_price": 79.99,
"categ_id": 2,
"description_sale": "Ergonomic wireless keyboard"
}'
Response
{
"success": true,
"data": {
"id": 5,
"name": "Wireless Keyboard",
"default_code": "KB001",
"list_price": 79.99,
"categ_id": {"id": 2, "name": "Peripherals"},
"active": true,
"qty_available": 0
},
"message": "Product created successfully"
}
Example 2: Create Order with API Key
Request
curl -X POST http://localhost:8069/api/v1/orders \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"partner_id": 3,
"order_lines": [
{
"product_id": 1,
"product_qty": 2,
"price_unit": 99.99
},
{
"product_id": 5,
"product_qty": 1,
"price_unit": 79.99
}
]
}'
Response
{
"success": true,
"data": {
"id": 10,
"partner_id": {"id": 3, "name": "John Doe"},
"amount_total": 259.97,
"state": "draft",
"order_lines": [
{
"id": 25,
"product_id": {"id": 1, "name": "Mouse"},
"qty": 2
}
]
},
"message": "Order created successfully"
}
Example 3: Create Customer
Request
curl -X POST http://localhost:8069/api/v1/customers \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "Content-Type: application/json" \
-d '{
"name": "Jane Smith",
"email": "jane@example.com",
"phone": "+1-555-0123",
"street": "123 Main St",
"country_id": 1,
"is_company": false
}'
Response
{
"success": true,
"data": {
"id": 8,
"name": "Jane Smith",
"email": "jane@example.com",
"phone": "+1-555-0123",
"street": "123 Main St",
"country_id": {"id": 1, "name": "Belgium"},
"is_company": false,
"active": true
},
"message": "Customer created successfully"
}
Example 4: Error Response
Missing Required Field
{
"success": false,
"error": {
"code": 400,
"message": "Missing required field: name"
}
}
Invalid JSON
{
"success": false,
"error": {
"code": 400,
"message": "Invalid JSON body"
}
}
Rate Limit Exceeded
{
"success": false,
"error": {
"code": 429,
"message": "Rate limit exceeded. Max 60 requests per minute"
}
}
Security Features
Data Protection
- Field whitelist sanitization
- Company isolation
- User context isolation
- Many2one relation protection
Access Control
- Scope-based permissions
- IP whitelist filtering
- Rate limiting enforcement
- API key revocation
Support & Documentation
For more information, visit the Swagger documentation at:
/api/docs
Please log in to comment on this module