OdooWiki OCA HUB

WebService Core

webservice_core folder_open OCA/web-api open_in_new
Uncategorised License: AGPL-3

This module provides the webservice.backend model with its authentication (public, username/password, API key) and HTTP call features (get/post/put/delete).

It has no dependency on component or server_environment, so it can be used as a lightweight building block by any module needing to configure and call an outbound webservice, without pulling in extra frameworks.

On top of a backend, you can configure specific, named webservice.endpoint records via the UI, instead of only building calls in Python via webservice.backend.call(method, url_args, ...). Each endpoint bundles a required description, a fixed HTTP method and relative path (appended to the backend URL), static headers, and an optional authentication override, fully independent from the backend's. Endpoints are called with endpoint.call(...); calling the backend directly with backend.call(method, ...) remains fully supported.

auto_awesome What this module does

AI-generated from the code · Odoo 18.0

Lets administrators register external web services (backends) and named endpoints with their URL, HTTP method, headers, query parameters and authentication, so other modules can call them without extra frameworks.

This module adds a configuration area for outbound web services. It appears under the Custom menu as two entries: WebService Backend and WebService Endpoint.

On a backend you record a name, a technical name, the base URL, the protocol (HTTP), a content type (JSON, XML or Form), a timeout, and how to authenticate: public, username & password, or API key (with the header name that carries the key). You can also list static headers and querystring parameters that are sent with every call. A smart button shows how many endpoints belong to the backend and opens them.

An endpoint belongs to a backend and adds a required description, a fixed HTTP method (GET, POST, PUT or DELETE), a relative path appended to the backend URL, and its own headers and querystring parameters. By default it reuses the backend's authentication; if you tick 'Override Authentication' you must choose an authentication type and fill its credentials, otherwise Odoo refuses to save.

Business rules: technical names are generated from the name and must be unique (per backend for endpoints); credentials required by the chosen authentication type are enforced; a copy/paste URL is displayed on both screens. Backends and endpoints are company-restricted in multi-company setups, and only administrators can manage them. The module itself only stores configuration; the actual calls are made by other modules or code.

Depends on

base

Required by other modules

Models and fields (5)
  • webservice.header · new modelname, value, res_id (Record), res_model
  • webservice.backend · new modelurl, name, company_id (Company), endpoint_ids (Endpoints), endpoint_count
  • webservice.endpoint · new modelname, path, active, protocol, auth_type, tech_name, backend_id, company_id, description, http_method, override_auth (Override Authentication)
  • webservice.request.mixin · new modelapi_key (API Key), timeout, password, protocol, username, auth_type, tech_name, header_ids (Headers), content_type, api_key_header (API Key header), full_url_display, querystring_param_ids (Querystring Params)
  • webservice.querystring.param · new modelname, value, res_id (Record), res_model

Text generated by AI (DeepSeek) from reading the Odoo 18.0 code on GitHub; it may contain mistakes, so check the code before deciding. View the code on GitHub

Availability by version

Reviewed: 2026-11-03
Confirmed (verified in repository and branch) Estimated (unverified) No information

Confirmation status: 1 confirmed, 8 with no information of 9 versions.

terminal Installation and usage

OCA documentation · Odoo 18.0

Go to Settings > Technical > WebService Backend (requires the Administration / Settings group) and create a new backend:

  • Name / Technical Name: a label and a unique technical key you'll use to look the backend up from code (e.g. env.ref is not used here; search by tech_name instead).
  • Protocol: only HTTP Request is available in this module.
  • URL: the base URL every call is relative to, e.g. https://api.example.com. It may contain {placeholder} tokens (see Usage), e.g. https://api.example.com/{endpoint}.
  • Content-Type: optional default Content-Type header for every call.
  • Timeout: optional timeout in seconds for the whole request (connect + read). Left empty, a call waits indefinitely.

Under the Headers and Querystring Params tabs you can configure static defaults, merged into every call (see Usage).

Then configure authentication via Auth Type:

  • Public: no credentials needed.
  • Username & password: sent as HTTP Basic Auth. Requires Username and Password.
  • API Key: sent as a custom header. Requires API Key and API Key header (the header name to send it under, e.g. X-Api-Key).

Required fields depend on the selected auth type; the form only shows and requires the ones that apply, and saving enforces it.

Each webservice.endpoint (see Description) has its own Content-Type, Timeout, Headers and Querystring Params, overriding the backend's own for that specific endpoint - set only what needs to differ.

Look up the backend (e.g. by its technical name) and call it:

backend = env["webservice.backend"].search([("tech_name", "=", "my_api")])
result = backend.call("get")  # -> the full requests.Response object

call(method, *args, **kwargs) accepts any of the standard HTTP verbs (get, post, put, delete) and forwards everything else to requests, so any of its keyword arguments work too (data, json, params, files, ...):

backend.call("post", data=b"<xml>...</xml>")
backend.call("post", json={"foo": "bar"})

URL: by default the backend's own url is used. Pass url to hit a different path - relative paths are appended to the backend's URL, a full http(s):// URL is used as-is:

backend.call("get", url="orders")  # -> <backend url>/orders
backend.call("get", url="https://other.example.com/orders")

If the backend's URL (or the url passed above) contains {placeholder} tokens, fill them with url_params:

# backend.url == "https://api.example.com/{endpoint}"
backend.call("get", url_params={"endpoint": "orders"})

Headers: pass headers to add/override headers for that call; they are merged on top of the backend's own static headers (configured in the "Headers" tab), Content-Type and auth-derived headers (e.g. the API key header) - the headers kwarg wins on matching keys:

backend.call("get", headers={"X-Request-Id": "42"})

Querystring params: sent via requests' params=, not to be confused with url_params above, which fills {placeholder} tokens in the URL path itself. Configure static defaults in the "Querystring Params" tab - a value there may itself contain a {placeholder}, resolved against the same url_params used for the URL. An explicit params kwarg passed to call() wins over the static configuration on matching keys:

backend.call("get", params={"verbose": "1"})

Auth override: pass auth to bypass the backend's configured auth type for a single call (same format requests itself accepts, e.g. a (user, password) tuple):

backend.call("get", auth=("other_user", "other_password"))

Timeout: pass timeout to override the backend's own configured timeout (in seconds) for a single call:

backend.call("get", timeout=5)

Response: call() always returns the full requests.Response object (status code, headers, content, ...):

response = backend.call("get")
response.status_code
response.content

No verified information in OCA: Installation.

info

Data imported from GitHub: this sheet reflects the latest catalog review, not a live lookup. Always check the module documentation and staging before installing in production.