This topic covers implementing a gRPC-based real-time data integration service. All new containers should be built for gRPC.
gRPC integration build guide
Complete the following steps to set up the proto files and generate the language-specific bindings your container requires. This uses protoc, the Protocol Buffers compiler, which converts .proto schema files into language-specific code. Installation instructions are available at grpc.io/docs/protoc-installation.
Download the official OpenRTB
An open industry standard for communication between buyers and sellers of online advertising in real-time bidding auctions. It's published by the IAB. 2.6 Protocol Buffers specification from the IAB Tech Lab's openrtb2.x repository.Clone the ARTF reference implementation repository, which contains the Makefile, build scripts, and proto files referenced in the steps below.
Generate the language-specific OpenRTB and gRPC bindings:
Install
makeandprotocv27 or later. This is required foredition = "2023"support; the version in most base package managers is too old and errors on--experimental_editions.Install the language plugins. For example, for Go:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latestOpen the Makefile and choose the languages under
LANGUAGES.Run
make bindings. Plainmakebuilds the reference agent, not the bindings.
Alternatively, skip generation and use the pre-generated Go bindings included in the repository under
pkg/pb/(pkg/pb/artf,pkg/pb/openrtb).
Classification endpoint
Partners must expose an endpoint
A URL which is configured to interact with a server in a specific way. accessible through a gRPC request following the agentic RTB
Real-Time Bidding (RTB). The automated buying and selling of inventory for advertisements in real time, which is within milliseconds of an individual user loading a site. Protobuf Schema downloaded with your build files.
The SLA for Index Exchange (Index) to use your response in auction processing is 5 milliseconds. No more than 3% of requests are allowed to exceed the tmax timeout value. If more than 3% of requests time out, traffic to your container is automatically throttled and Index may lower QPS
Queries Per Second (QPS). The number of bid requests a DSP processes per second. Also known as impressions per second. accordingly. Calls use keepalive connections to minimize network overhead.
Response codes
Standard gRPC status codes should be returned.
Circuit breaker logic
If Index receives any status code other than OK, or more than 3% of requests have exceeded an internal timeout value of 30ms, Index's circuit breaker triggers and requests to your container are throttled. Requests that time out also trigger this logic.
Circuit breaker logic protects both Index and partner systems from cascade failures. Once error rates return to nominal levels, measured over a rolling window, circuit breakers reopen and regular traffic volume resumes automatically. No action is required from your side during recovery.
Note: The circuit breaker uses a 30ms internal timeout for both gRPC and HTTP integrations. The 5ms figure is the SLA for your response to be used in auction processing; the 30ms figure is the outer timeout after which Index treats the request as failed for circuit breaker purposes.
gRPC-supported lifecycle extension points and mutations
The following table summarizes all supported lifecycle extension points, the mutations available at each, and their paths. For full schema details and examples, see the Mutation reference.
What your container receives
At the Publisher Request extension point, your GetMutations handler receives an RTBRequest whose bid_request field holds the full privacy-safe OpenRTB payload. For the fields included in that payload, see the Publisher request payload reference. Index calls GetMutations in real time during auction processing, once per extension point.
Two other RTBRequest fields matter for every call:
tmaxis the maximum number of milliseconds Index waits for your response. Treat it as a hard deadline.applicable_intentsis the list of mutation intents Index accepts on that call. Filter your mutations to only these; a mutation whose intent is not inapplicable_intentsis silently discarded.
Note: The bid_response field is empty at the Publisher Request extension point. It is only populated when lifecycle is LIFECYCLE_DSP_BID_RESPONSE. Note that device.ip, device.geo.lat, device.geo.lon, and device.geo.zip may be anonymized, masked, or withheld depending on the request user's privacy settings. See the Publisher request payload reference for the full list of modifications.
The following is an example of a complete RTBRequest at the Publisher Request extension point, in protojson format:
{
"id": "2545D87B17C8853B",
"lifecycle": "LIFECYCLE_PUBLISHER_BID_REQUEST",
"tmax": 5,
"applicable_intents": [
"ACTIVATE_SEGMENTS", "ACTIVATE_DEALS", "SUPPRESS_DEALS",
"ADJUST_DEAL_FLOOR", "ADD_CIDS"
],
"bid_request": {
"id": "2545D87B17C8853B",
"imp": [{
"id": "1",
"banner": { "w": 300, "h": 250, "pos": 1, "format": [{ "w": 300, "h": 250 }] },
"bidfloor": 0.5,
"ext": { "gpid": "/1234567/home/mpu/atf", "sid": "abc123" }
}],
"site": {
"id": "12345", "domain": "example.com",
"page": "https://example.com/section/",
"publisher": { "id": "555555", "domain": "example.com", "name": "Publisher Name" }
},
"device": {
"connectiontype": 2, "devicetype": 2, "dnt": 0,
"ip": "2001:db8::", "language": "en", "lmt": 0,
"ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/114.0.0.0"
},
"regs": { "coppa": 0 },
}
}Note: lifecycle, id, tmax, and bid_request are required on every RTBRequest and must be set on every call. In particular, bid_request is required even at LIFECYCLE_DSP_BID_RESPONSE, where you operate on bid_response. Omitting it fails to marshal. Echo id back unchanged in RTBResponse.id.
What your container returns
Your GetMutations handler returns an RTBResponse containing the following fields:
| Field | Purpose |
|---|---|
| Echo the |
| The list of mutations you want applied. Return an empty list if you have nothing to contribute. |
|
|
Implementation pattern
Structure your handler as follows:
Respect
tmax. Set a deadline on any inner work usingcontext.WithDeadline.Read signals from
bid_request, and frombid_responseon the post-bid path.Filter by
applicable_intents. Only build mutation types that are eligible for this call.Build mutations per the schema (
intent,path,op,value). Use one mutation per entity.Return the response with the same
id, your mutations, andmetadata.
Next: Implement whichever mutations you need. See Mutation reference for the schema of all six, and Implementing bid shading for additional depth if bid shading is one of them. If you are deploying in Index Cloud, continue to Building your container to package your container, then validate it with Using the Index testing tool. If you are hosting the service yourself, validate your implementation with Using the Index testing tool; your container is ready to deploy to your own infrastructure once it passes.