general 17.06.2026 ~9 min read

Connecting Python to 1C via OData REST API

Discover how integrating Python with 1C via OData REST API can change the approach to data exchange and improve business processes. Simplicity and efficiency in one solution! #Python #1C #OData #RESTAPI #integration

Connecting Python to 1C via OData REST API

Title: Connecting Python to 1C via OData REST API

Text: The standard OData interface appeared in the 1C:Enterprise platform back in version 8.3.5 — this is the 2015 release. Since then, any configuration can automatically provide directories, documents, and registers via the OData protocol version 3.0, without a single line of code on the 1C side. Data comes in JSON or XML, and requests are built directly in the address bar using the $filter, $orderby, and $select parameters. Yet, ten years later, we regularly see companies where data exchange with websites, analytics, or external services relies on manual CSV exports and nightly tasks that break with any structural change. The gap between what the platform can do out of the box and how it is used in practice remains huge.

In our practice at West Star Ltd, a significant part of integration tasks boils down to this: providing external Python code with safe and predictable access to 1C data without modifying the configuration itself. The thesis of this article is simple. OData in 1C is not an exotic or temporary solution, but a full-fledged REST interface on which you can build reporting, synchronization with marketplaces, chatbots, and web services. Below, we'll go through the steps to set up this interface, how to read and write data from Python, and where the real boundaries of the approach lie.

WHY ODATA AND NOT EXPORTS

The main value of OData is that it is a standard, not a custom format. Any language, any BI system, any HTTP client understands the same rules: how to request a list of entities, how to filter rows, how to get metadata. There's no need to agree on file structure, parse encodings, or monitor delimiters. A GET request to the address /odata/standard.odata/$metadata returns a complete description of all available entities, their fields, and types — this is a self-documenting contract between 1C and the outside world.

The second advantage is real-time operation. Manual export always shows the database's state as of yesterday, while OData provides data at the time of the request. This is critical for warehouse balances, order statuses, and settlements. The third point is server-side filtering. Instead of exporting the entire nomenclature and slicing it in Python, we ask 1C for exactly the rows we need, saving both traffic and time.

HOW TO ENABLE THE STANDARD INTERFACE

The interface does not work by itself — it needs to be published on a web server. When publishing the information base via Apache or IIS, the publication settings include a flag for the availability of the standard OData interface, and the platform itself generates a REST point for the entire configuration. After that, the database responds at an address like http://server/base_name/odata/standard.odata/.

Next — permissions. The user under which the external code operates needs the RemoteAccessOData role, otherwise, the platform will return an access error. We strongly advise creating a separate service user for integration with the minimally necessary set of rights, rather than connecting under a full administrator. This is both safer and allows access to be revoked at any time without affecting live employees. The composition of entities visible through OData is also configured in the configurator — you can expose only the necessary directories and documents, leaving the rest closed.

FIRST REQUEST FROM PYTHON

Authentication in the standard interface is regular HTTP Basic. In Python, everything fits into a few lines using the requests library:

import requests

base = "http://server/base/odata/standard.odata"
auth = ("odata_user", "password")

resp = requests.get(
    base + "/Catalog_Nomenclature",
    params={"$format": "json", "$top": 10},
    auth=auth,
)
data = resp.json()
for item in data["value"]:
    print(item["Description"], item["Code"])

Here, pay attention to the names of the entities. Directories are addressed as Catalog_ plus the directory name, documents as Document_ plus the name, information registers as InformationRegister_ plus the name, and accumulation registers as AccumulationRegister_ plus the name. The $format parameter with the value json requests JSON instead of XML, $top limits the selection. The response always comes as an object with a value array — this should be considered when parsing.

FILTERING, SORTING, AND SELECTING FIELDS

The full power of OData is revealed in the request parameters. The $filter parameter transfers the selection condition to the 1C side. For example, to select only items not marked for deletion:

params = {
    "$format": "json",
    "$filter": "DeletionMark eq false",
    "$orderby": "Description asc",
    "$select": "Ref_Key,Code,Description",
}

The $orderby parameter sets sorting, $select limits the set of returned fields — this noticeably speeds up the response on large directories. Filters support comparison operators eq, ne, gt, lt, logical and and or, as well as functions like startswith and substringof for strings. Reference fields are compared using the cast construction with the indication of guid and entity type — this is the most non-obvious part of the syntax that almost all beginners stumble upon. To parse the structure, we always start with the $metadata request: it shows the exact field names, which do not always match what the user sees in the 1C interface.

WRITING DATA BACK TO 1C

OData in 1C works not only for reading. You can create a new directory item or document via POST with a JSON body, modify an existing one via PATCH by the Ref_Key, and post a document by calling the special Post function on the corresponding entity. A simple example of creating a contractor:

new_item = {"Description": "LLC Chamomile", "Code": "00-001234"}
resp = requests.post(
    base + "/Catalog_Contractors?$format=json",
    json=new_item,
    auth=auth,
)

We view writing with more caution than reading. Direct document creation bypassing the configuration's business logic can easily lead to incorrect register movements, so for complex operations, we prefer not to write the document directly through OData but to call an HTTP service written on the 1C side, where all necessary checks are performed. OData is perfect for reading and writing simple flat objects but does not eliminate the responsibility for accounting integrity.

HOW TO INTEGRATE THIS INTO DJANGO

In a Django web project, we usually do not scatter requests calls across views but create a thin client layer — a separate module that encapsulates the address, authentication, and response parsing. Views and background tasks then refer to it without knowing protocol details. Heavy selections are cached or stored in the project's database tables through Celery background tasks, so each user request does not directly hit 1C. This approach provides two things at once: website pages do not depend on whether the 1C database is currently alive, and the load on it remains predictable. Secrets — the address, login, and password of the service user — are moved to environment variables, not code, and access to OData is restricted by the network so that it is visible only to our application, not the entire internet.

LIMITATIONS AND WEAK SPOTS

OData in 1C is a working tool, but it's more honest to know its boundaries right away.

— Performance on large volumes. The standard interface does not like selections of hundreds of thousands of rows in one request. Without pagination through $top and $skip, heavy requests put a load on the 1C server and hit timeouts.

— Protocol version. The platform provides OData version 3.0, not the more recent 4.0. Some modern clients and libraries designed for 4.0 do not fully work with it or require manual adjustments.

— Fragile filter syntax. Comparison by references through cast with guid, Cyrillic encoding in URLs, case-sensitive field names — all these are sources of elusive errors. Without the $metadata request, assembling a working filter the first time is almost impossible.

— Field names do not match the interface. What an accountant sees as Contractor in OData may be called differently and have a technical postfix. This constantly confuses those who come from accounting rather than development.

— Business logic is not guaranteed. Direct document writing through OData bypasses configuration checks. For everything that affects postings and register movements, it is safer to go through 1C HTTP services rather than the standard interface.

— Default security is weak. Basic authentication without HTTPS means transmitting the password almost in plain text. Without channel encryption and network restrictions, open OData quickly becomes a hole.

WHAT TO DO IN PRACTICE

A developer should start small: publish the database with OData enabled on a test environment, request $metadata, and assemble the first working filter on the nomenclature directory. This removes most of the fear of the protocol in one evening. Next — move access to a separate client module and do not go to 1C from each view directly.

For a team leader, it's important to establish rules: a separate service user with minimal rights, access only through a secure channel, reading through OData, and complex writing through HTTP services. These three decisions cover most risks before development even begins.

A business owner only needs to understand the main thing: data already in 1C can be provided to the website, analytics, and chatbots in real-time, without expensive accounting restructuring and without manual exports. It's a matter of setup and a few days of work, not a separate large project. If the exchange currently relies on file exports, switching to OData almost always pays off by reducing the number of manual errors.

FREQUENTLY ASKED QUESTIONS

Do you need to modify the 1C configuration to enable OData?

No. The standard interface is generated by the platform automatically. It's enough to publish the database on a web server with the OData flag enabled and grant the user remote access role. Code on the 1C side is only needed if you want more complex business logic through HTTP services.

Which data format is better to use — JSON or XML?

For integration with Python and web services, JSON is more convenient: it is easier to parse and more compact. Just add the $format parameter with the value json or the Accept header with the value application/json. XML remains for systems that historically work with Atom.

Can you not only read but also write data through OData?

Yes, creation via POST, modification via PATCH, and deletion are supported. But for documents affecting accounting, we recommend writing through 1C HTTP services with full business logic checks, and using OData primarily for reading and simple objects.

How safe is it to open this externally?

By itself — not safe. A secure channel, a separate user with minimal rights, and network access restrictions are mandatory. With these conditions met, the risk is comparable to any other internal API.

general
Share Article

Comments (0)

No comments yet. Be the first!

Need 1C Integration?

We implement integration using Django + 1C OData API. Contact us for a free consultation.

Discuss Project