
Bring Odoo data into your application
Use records from your own Odoo instance as an external source for application resources. The binding identifies the Odoo model and its record key; deployment configuration supplies the instance and credentials.
Choose read-through for remote reference data or a local pipeline when your application needs to enrich and retain its own copy.
Example — Add internal context to customer accounts
An application imports company records from Odoo’s customer model and adds local notes. Odoo remains the source for the mapped company fields; the application owns the notes.
For engineers
The backend provider named odoo resolves ODOO_BASE_URL, ODOO_DB, ODOO_LOGIN and the secret ODOO_API_KEY. These belong in deployment configuration, not in frontend code or a committed resource binding. The resource chooses HttpApiTransportDialect.ODOO_JSONRPC, providerRef: 'odoo' and its entityRef.
Declare odoo in the backend’s provider scope with protocols: ['REST_API']; it needs no engine capability for a binding that addresses it by reference. Synchronize the provider artifacts after configuration changes. The account must be able to read the requested Odoo model.
The following is the binding and mapping portion of Wonder Todos’ externalCustomers pipeline. Its resource schema, operations and registration surround this excerpt. The imports for these enums come from @wildo-ai/saas-models/external-data.
externalDataPipeline: {
binding: {
dialect: HttpApiTransportDialect.ODOO_JSONRPC,
providerRef: 'odoo',
entityRef: 'res.partner',
keyFields: [{ localField: 'id', remoteField: 'id', codec: HttpApiKeyComponentCodec.INTEGER }],
tenancy: {
stance: HttpApiTenancyStance.SINGLE_TENANT_BINDING,
justification: 'Wonder Todos serves one company, whose Odoo holds one client list; there is no per-tenant partition to push down.',
},
erasure: { stance: HttpApiErasureStance.NO_SUBJECT_DATA },
},
remoteKeyLocalField: 'odooPartnerRef',
mapping: [
{ kind: ExternalDataMappingEntryKind.REMOTE_FIELD, remoteField: 'name', localField: 'name' },
{ kind: ExternalDataMappingEntryKind.REMOTE_FIELD, remoteField: 'email', localField: 'email' },
],
sourceFilter: { is_company: true },
population: ExternalDataDestinationPopulation.CLOSED,
orphanPolicy: ExternalDataOrphanPolicy.REPORT,
scheduleCron: '0 * * * *',
},
The integer remote key identifies the source record; odooPartnerRef retains that identity on the local destination. The mapping names the fields the import owns. The company filter supports this example’s stated data scope, and REPORT records missing source records without deleting local rows. These tenancy and erasure declarations describe this application; reassess them for a different population or customer account model.
For this dialect, the shared client authenticates the configured login to obtain an Odoo user ID, then puts database, user ID and key in the RPC arguments. It does not use the provider’s generic Bearer header for these calls. The compiler translates supported queries into model calls and domain filters; the pipeline owns scheduling and local reconciliation.
Define the data contract
The external data guide shows the complete company-account pipeline. Its res.partner binding uses integer id keys and a company-only source filter. The filter matters because the declared erasure stance describes company records, not individual contacts.
A virtual binding uses the same client but leaves records remote. Register the resource and provider protocol through their normal registries; naming a provider in providerRef does not install its package or provision the remote account. The configured Odoo account must have access to the requested model and operations.
Keep compatibility tied to the configured server
This connector targets the classic JSON-RPC contract implemented by its compiler and client. Protocol-simulator tests exercise authentication, extraction and changing source populations; they do not certify every hosted Odoo version or deployment. Verify the instance’s exposed API and permissions before depending on it for a business workflow. The provider is addressed by reference for these bindings rather than selected through an Odoo engine-capability slot.