In this post, I’ll walk you through how to call the Oracle Private AI Services Container’s REST endpoint from PL/SQL to generate vector embeddings over HTTP, step by step.

We recommend using HTTP only for development or internal proof-of-concept. A follow-up blog shows how to configure the Oracle Private AI Services Container for HTTP/SSL, delivering secure, production‑grade deployments.

It is also important to remember the Oracle Private AI Services Container should be hosted on a separate server from the Oracle AI Database 26ai to free up CPU resources and prevents database tasks from being blocked during embedding generation, ensuring optimal performance for both systems.

Let’s get started.

Accessing the Oracle Private AI Services Container using a REST endpoint

Prerequisite – A Running Oracle Private AI Services Container

I’m going to assume you already have the Oracle Private AI Services Container running, and its REST endpoint exposed. Please refer to the Oracle Private AI Services Container User Guide for more information such as download, setup, and installation.

First let’s verify the container’s status on its host with the following podman ps command.

podman ps
CONTAINER ID IMAGE                                                        COMMAND CREATED       STATUS        PORTS                  NAMES
b2b31fee8066 container-registry.oracle.com/database/private-ai:25.1.2.0.0         9 seconds ago Up 10 seconds 0.0.0.0:8080->8080/tcp privateai

You’ll see that the container was started with HTTP enabled and is running on port 8080.

1. Check the REST Endpoint

Now run the following curl command to send an HTTP GET request to the container’s /health endpoint on the default port 8080 and includes the HTTP response headers in the output.

curl -i http://your-fully-qualified-hostname:8080/health

The expected response looks like this:

HTTP/1.1 200 OK
date: Thu, 12 Feb 2026 14:07:00 GMT
x-ratelimit-limit-requests: 60
x-ratelimit-remaining-requests: 59
x-ratelimit-reset-requests: 1
x-server-id: b6d4c06e-490c-4988-9012-6fd3f959ce51
content-length: 0

A “200 OK” response indicates that the Oracle Private AI Services Container is running and ready for requests.

2. Grant the http or connect privilege for the container’s host

A network ACL must be created by a DBA so the Oracle schema can call the Oracle Private AI Services Container over HTTP.

The PL/SQL block below grants an access‑control entry (ACE) with the HTTP privilege to the user vectordb on “host”, which is your‑fully‑qualified‑hostname (port 8080 only).

Alternatively, you could grant the CONNECT privilege. It provides additional capabilities that we don’t need for this example.

For more information on granting ACE privileges, see the Oracle AI Vector Search User’s Guide.

The same section also explains how to configure a proxy server (if applicable).

 BEGIN
      DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
          host => 'your-fully-qualified-hostname',
          lower_port => 8080,
          upper_port => 8080,
          ace => xs$ace_type(privilege_list => xs$name_list('http'),
                             principal_name => 'vectordb',
                             principal_type => xs_acl.ptype_db));
 END;
 /

This procedure appends an access control entry (ACE) to the access control list (ACL) of a network host. The ACL controls access to the given host from the database and the ACE specifies the privileges granted to or denied from the specified principal.

2.1 Quick verification

The database view USER_HOST_ACES shows the ACEs that have been granted to the current schema. You can run this query to verify that the ACE was granted successfully.

SELECT host, lower_port, upper_port, privilege, status
FROM user_host_aces;

HOST                          LOWER_PORT UPPER_PORT PRIVILEGE STATUS
----------------------------- ---------- ---------- --------- -------
your-fully-qualified-hostname 8080       8080       HTTP      GRANTED

If the row shows host = ’your-fully-qualified-hostname’, privilege = ‘http’, lower_port = ‘8080’, upper_port= ‘8080’ and status = ‘GRANTED’, the ACE entry is in place.

The database user vectordb can now issue HTTP requests to http://your-fully-qualified-hostname:8080/

A single misconfiguration is all it takes to break the connection: a typo in the host name, an incorrect port, or a missing ACL will cause the call to the container’s REST endpoint (which we’ll cover in the next step) to fail with ORA‑29273, “HTTP request failed.”

To obtain a detailed error message and identify a missing or incorrect ACL, query the UTL_HTTP.GET_DETAILED_SQLERRM function:

SELECT UTL_HTTP.GET_DETAILED_SQLERRM;

GET_DETAILED_SQLERRM
--------------------------------------------------------------------------------
ORA-24247: network access denied by access control list (ACL)

Call the Container’s Embedding Endpoint from PL/SQL

We are now ready to start generating vectors. Let’s run the following PL/SQL to invoke the Private AI Services Container’s REST API, generate an embedding from a plain-text CLOB “hello”, and output the resulting vector.

SET SERVEROUTPUT ON

DECLARE
input clob;
v vector;
BEGIN
  input := 'hello';
   v := DBMS_VECTOR.UTL_TO_EMBEDDING(
    input,
    json('{"provider": "privateai",
    "url": "http://your-fully-qualified-hostname:8080/v1/embeddings",
    "host": "local",
    "model": "all-MiniLM-L12-v2" }'));
   DBMS_OUTPUT.PUT_LINE(vector_serialize(v));
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE (SQLERRM);
    DBMS_OUTPUT.PUT_LINE (SQLCODE);
END;
/ 

The above PL/SQL block loads a simple text string (“hello”) into a CLOB and calls the DBMS_VECTOR.UTL_TO_EMBEDDING function with a JSON payload that points to the container’s /v1/embeddings endpoint. It specifies the Private AI Services Container’s provider as “privateai,” uses “local” to skip the need to pass a credential, and references the model “all‑MiniLM‑L12‑v2” that generates the embedding. The resulting vector is serialized with VECTOR_SERIALIZE and printed via DBMS_OUTPUT. An exception block catches any errors and reports the error message and code.

With the all-minilm-l12-v2 model, each embedding is a 384‑element vector; so I’ll only show a subset of its dimensions for readability.

[-7.49069378E-002,-1.44330524E-002,4.86498736E-002,-2.71381401E-002,-4.30881716E
-002,-1.47763431E-001,6.88331053E-002,-1.37038641E-002,-5.35686985E-002,2.697533
93E-002,-6.28336193E-003,-3.98834497E-002,7.65678007E-003,-3.78089584E-002,-1.17
557691E-002,-3.46409418E-002,1.29357159E-001,-2.52777934E-002,-1.52099188E-002,7
.30306434E-004,-8.06887969E-002,2.69378684E-002,-9.87357348E-002,-3.4107659E-002
,-2.70293821E-002,-7.32003525E-002,5.08588664E-002,-1.72562916E-002,7.28218406E-
...
8.3617419E-002,3.61523218E-002,-2.27608532E-002,1.09307049E-002,-4.64
579426E-002,-2.51197256E-002,3.10343243E-002,1.40036587E-002,2.80777384E-002,-7.
75460526E-003,-3.13466117E-002,5.54158725E-002]

The first time you invoke an embedding model—for example, the all‑minilm-l12-v2 model—there’s a short pause of a few seconds. That delay occurs because the model is loaded from disk into memory and cached for subsequent use. After that initial load, subsequent calls are essentially instantaneous.

Summary

This post shows how to generate vector embeddings from Oracle AI Database 26ai by calling the Oracle Private AI Services Container over HTTP from PL/SQL. It walks through the end-to-end setup: confirming the container is running and reachable via a REST health check, creating the required network ACL/ACE so a database schema can connect to the container’s host and port, and then invoking the container’s /v1/embeddings endpoint using DBMS_VECTOR.UTL_TO_EMBEDDING. You also learned what to expect at runtime (including the first-call model load delay) and how to troubleshoot common connectivity issues such as missing ACLs (for example ORA‑24247/ORA‑29273). A follow-up post will cover moving from HTTP to HTTP/SSL for secure, production-grade deployments.

Resources