Remote Feed Hosted Store Guide
Client guide for writing to and reading from a StreamingFast-managed Remote Feed Hosted Store
A Remote Feed Hosted Store is a managed, block‑aware key/value store that StreamingFast runs for you. You write key/value entries into it over gRPC, and your Substreams modules — or any gRPC client — read those entries back at a given block height.
This guide is for the Remote feed flavor of a Hosted Store: you (or another service) push values in. For a package that reads the chain and populates the store, see the Substreams Feed Hosted Store Guide.
This guide shows you how to:
Understand what a hosted store is and when to use it
Create one and get its endpoint
Authenticate
Write entries into it (
Feed.Set) and delete them (Feed.Delete)Read entries back, either directly (
Store.Get/Store.GetFirst) or from a Substreams moduleLook up the proto reference
1. Concepts
A hosted store is a key → value map with a few blockchain‑specific properties:
Keys are raw
bytes— they can be a string, a hash, an address, or any composite key you choose.Values are a
google.protobuf.Any— i.e. any protobuf message you define, tagged with its@type.Readiness — a store starts not ready. Direct
Get/GetFirstthen report the store hasn't reached the requested block yet (even if the keys are already written). A Substreams that queries a not‑ready store hangs until you flip it ready withFeed.SetReady.Block‑aware reads — every read targets a specific block number. The response tells you whether the store has ingested up to that block yet (
block_reached = true). Ifblock_reachedisfalse, treat the result as not-yet-final rather than as "key not found".
You populate a hosted store by writing entries directly over gRPC with Feed.Set, and remove them with Feed.Delete (the remote feed flow). Data written or deleted this way is treated as already final. You can query the same keys directly over gRPC or from a Substreams module — but a Substreams hangs if the store is not marked ready (see below), while a direct Get returns immediately with block_reached = false.
2. Create a Remote Feed Hosted Store
Stores are provisioned through The Graph Market, under Hosted Services:
https://thegraph.market/sinks/new — create a new service.
Choose Hosted Store.
Set the feed mode to Remote feed (off‑chain writes over gRPC). For a package that populates the store from the chain, use the Substreams Feed Hosted Store Guide instead.
Give it a name and a Type URL.
https://thegraph.market/sinks — list your services and copy the store's deployment ID.
Creating a Remote Feed Hosted Store only requires two fields:
Name — a label for the store.
Type URL — the fully‑qualified protobuf type of the values you'll feed in (e.g.
com.acme.example.v1.TestValue). The protobuf package and message name are entirely free‑form — pick whatever fits your own project, this is not a StreamingFast‑defined type.
When you create one you get back a deployment ID (e.g. depxado8480c1026b3edb7f). That ID is used in two places:
as the hostname of the store's gRPC endpoint, and
as the store reference in a Substreams manifest.
Endpoint convention
Once deployed, the store is reachable at:
Example: depxado8480c1026b3edb7f.hs.streamingfast.io:443
TLS on port 443, gRPC over HTTP/2.
Authenticated with an API key (see next section).
Generating client bindings
The store's Protobuf definitions are published on the Buf Schema Registry at buf.build/streamingfast/substreams-foundational-store — you don't need to vendor the .proto files locally. Point buf generate at the remote module and pick the plugin for your language, e.g. for Rust with a buf.gen.yaml:
See the Buf Generate docs for Go, TypeScript, Python, and other language plugins.
3. Authentication
Calls to the store carry a StreamingFast API key in the gRPC x-api-key metadata:
An API key is created automatically when you create the store, so you don't have to make one yourself beforehand. Manage your keys at https://thegraph.market/api-keys.
4. Write and delete entries
The remote‑feed ingest service is sf.substreams.foundational_store.feed.v2.Feed. Set writes a batch of entries; Delete removes a batch of keys. Both are treated as final and applied immediately (latest‑value semantics, no fork handling).
Entry shape
See SinkEntries and Entry on the Buf Schema Registry:
Calling Feed.Set
Send Set from the Buf Schema Registry explorer for sf.substreams.foundational_store.feed.v2:
Open that page and select Set.
Set the target to
<deployment-id>.hs.streamingfast.io:443.Add metadata
x-api-key: <api-key>.Fill the
SinkEntriesrequest: one or moreEntryvalues, each withkey.bytesand agoogle.protobuf.Anyvalue.
Notes:
key.bytesis base64 in JSON (gRPC bytes encoding).valueis agoogle.protobuf.Any: the@typemust be the fully‑qualified type URL of your value message, and the remaining fields are that message's fields.Use
"if_not_exist": trueat theentrieslevel to avoid overwriting existing keys.
Deleting keys — Feed.Delete
Delete removes a batch of keys. Missing keys are ignored. Like Set, the delete is treated as final and applied immediately.
See DeleteRequest on the Buf Schema Registry:
Send Delete from the same Buf Schema Registry explorer for sf.substreams.foundational_store.feed.v2:
Open that page and select Delete.
Set the target to
<deployment-id>.hs.streamingfast.io:443.Add metadata
x-api-key: <api-key>.Fill
keyswith one or morekey.bytesvalues.
Notes:
key.bytesis base64 in JSON (gRPC bytes encoding).An empty
keyslist is a no-op; missing keys are ignored — the call still succeeds.This is a hard delete. A later
Get/GetFirstreturnsRESPONSE_CODE_NOT_FOUND. It does not write a tombstone and does not returnRESPONSE_CODE_NOT_FOUND_FINALIZE.
Marking the store ready
A new store is not ready. Hold reads off while you populate it, then flip the flag with Feed.SetReady — same Buf page, select SetReady, and send { "ready": true }.
Until you call SetReady with ready = true:
Direct
Get/GetFirstreturnblock_reached = false— even if the keys are already written.A Substreams that queries the store hangs. It does not error, skip, or time out; the runtime treats
block_reached = falseas "try again later" and waits until the store is marked ready, then continues.
Call SetReady only after the data consumers need is written. If a Substreams appears stuck on the first block after you added a hosted‑store input, the store is almost certainly still not ready.
5. Read entries
Option A — query the store directly (Store.Get)
The query service is sf.substreams.foundational_store.service.v2.Store. Reads are performed at a block and return one result per requested key, in order. See GetRequest and GetResponse:
Call Get and GetFirst from the Buf Schema Registry explorer for sf.substreams.foundational_store.service.v2:
Open that page and select Get or GetFirst.
Set the target to
<deployment-id>.hs.streamingfast.io:443.Add metadata
x-api-key: <api-key>.Set
block_numberand thekeysto look up (key.bytesis base64 in JSON).
Getreturns exact key matches.GetFirstreturns, for each requested key, the first key ≥ it (lexicographic order) — useful for range scans / "next key" lookups.
Response codes
Each QueriedEntry carries a code:
RESPONSE_CODE_FOUND (1)
Key exists; entry holds the value.
RESPONSE_CODE_NOT_FOUND (2)
Key does not exist at the requested block.
RESPONSE_CODE_NOT_FOUND_FINALIZE (4)
Key was deleted after finality (historical reference).
RESPONSE_CODE_UNSPECIFIED (0)
Should not occur.
Feed.Delete is a hard delete: subsequent reads of that key return NOT_FOUND, not NOT_FOUND_FINALIZE.
Always check block_reached first: if it's false, the store hasn't ingested the block you asked about yet (or it isn't marked ready), and a NOT_FOUND doesn't mean the key is truly absent.
Option B — read from a Substreams module
This is the most common consumption path: your Substreams module declares the hosted store as an input and queries it per block.
1. Declare it in substreams.yaml
Add the store as a module input using foundational-store: <deployment-id>@<version>:
Note: the
@<version>suffix (e.g.@v0.1.0) is ignored by the system — the store is resolved by its deployment ID alone — but it must be present to pass manifest validation.
Add the proto dependency in buf.yaml so the hosted store types are available:
2. Query from a Substreams
The store is injected into your handler as a FoundationalStore. Call get with a slice of keys; you get back a QueriedEntries.
The read is automatically performed at the block currently being processed, so results stay in sync with the stream.
Not ready ⇒ hang. If the store is not marked ready,
store.get(...)does not return. The Substreams stalls at that block until someone callsFeed.SetReadywithready = true. This is intentional: the runtime treatsblock_reached = falseas "try again later", not as a miss. DirectGet/GetFirststill return immediately withblock_reached = false.
3. Build and run
(During local development against a dev stack you might use -e localhost:9088 --insecure --limit-processed-blocks=0.)
6. End‑to‑end checklist
Create a Remote Feed Hosted Store in The Graph Market (Hosted Services → Hosted Store → Remote feed) → note the deployment ID.
Listen for a response from the endpoint. The Store is now running.
Authenticate with an API key (
x-api-key).Write your entries with
Feed.Set(andFeed.Deleteto remove keys), then callFeed.SetReady. A Substreams that queries the store before that hangs until you mark it ready.Read them either directly with
Store.Get/Store.GetFirst, or by addingfoundational-store: <deployment-id>@<version>to a Substreams module and callingstore.get(...).
7. Proto reference
The authoritative message and service definitions — model/v2/model.proto, feed/v2/feed.proto, and service/v2/service.proto — are published at buf.build/streamingfast/substreams-foundational-store. Browse them there, or see the Foundational Store Reference for the architecture and data model behind them.
Related resources
Hosted Services — the managed Sink and Store offerings StreamingFast runs for you.
Substreams Feed Hosted Store Guide — let a Substreams package populate the store from the chain.
Foundational Stores — chain-specific foundational stores populated by a Substreams package.
Consuming a Foundational Store — querying a foundational store from a Substreams module, imported as a package.
Hosting a Foundational Store — running your own foundational store server instead of using a StreamingFast-managed one.
Foundational Store Reference — architecture and data model shared by both hosted and self-hosted stores.
Last updated
Was this helpful?

