Getting started
Start without any setup: get your virtual key, change the base_url in the OpenAI SDK, and send your first masked request within minutes.
Two addresses and one virtual key are all you need for your first request.
There is nothing to install; if you use the OpenAI SDK, you only change the
base_url value and the key, and the rest of your code stays the same.
Your access details
| Use | Address |
|---|---|
API base (OpenAI SDK base_url) |
https://gw-tr.gurubase.io/v1 |
| Management panel | https://gateway-tr.gurubase.io |
Generate your virtual key
Sign in to the panel and generate a virtual key; you send your requests with this key. The language model provider’s real key stays inside the Gateway, so you never keep it in your application. See Panel for the steps.
First request
All three examples below send the same request to the Responses API. The text contains a name and a Turkish national ID number (TCKN); both are masked before they reach the model.
curl https://gw-tr.gurubase.io/v1/responses \
-H "Authorization: Bearer $SANAL_ANAHTAR" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"input": "Ayşe Demir, TCKN 10000000214, başvuru durumunu soruyor."
}'from openai import OpenAI
client = OpenAI(
base_url="https://gw-tr.gurubase.io/v1",
api_key="SANAL_ANAHTAR",
)
resp = client.responses.create(
model="gpt-4o-mini",
input="Ayşe Demir, TCKN 10000000214, başvuru durumunu soruyor.",
)
print(resp.output_text)import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gw-tr.gurubase.io/v1",
apiKey: process.env.SANAL_ANAHTAR,
});
const resp = await client.responses.create({
model: "gpt-4o-mini",
input: "Ayşe Demir, TCKN 10000000214, başvuru durumunu soruyor.",
});
console.log(resp.output_text);What happened?
The name and the TCKN in your input were replaced with placeholders in the copy sent to the model:
Input : "Ayşe Demir, TCKN 10000000214, başvuru durumunu soruyor."
Response you get : "<KİŞİ_1>, TCKN <TCKN_1>, başvuru durumunu soruyor."
The model works with the masked text, and the placeholders are preserved in the response and reach you in the plain form above. If your code looks for placeholders, this is the form to match.
The placeholder in the copy sent to the model is per-request (not <KİŞİ_1>;
it carries a unique suffix). That is deliberate: a predictable placeholder would
open the door to values being mixed across requests. Nothing changes on your
side, because the response comes back to you in the plain form.
The direct /mask endpoint is different: there placeholders come back with raw
category names such as <PERSON_1>. For the comparison table and how this
differs from what the panel displays, see Concepts.