Data Requests allow you to retrieve information from public API endpoints that do not require sensitive credentials like API keys. For APIs that do require keys, see Advanced: API-key Gated Data.
In this walkthrough, we'll use the , which includes all necessary dependencies to build and test an Oracle Program.
HTTP Fetch: GET
The httpFetch method is available only during the execution phase.
Attempting to use it in the tally phase will cause an error due to its non-deterministic nature.
Example using the http_fetch method:
use seda_sdk_rs::{http_fetch, log, oracle_program, Process};
#[oracle_program]
impl MyDataRequest {
fn execute() {
let response = http_fetch("https://pokeapi.co/api/v2/pokemon-species/mewtwo", None);
if !response.is_ok() {
Process::error("Could not fetch API endpoint".as_bytes());
return;
}
let response_str = String::from_utf8(response.bytes).unwrap();
log!("Response: {}", response_str);
}
fn tally() {
panic!("Not implemented");
}
}
Running this program with the following test will output the result of the execution, showing the http_fetch response as a string. You can place this test in tests/my-dr.test.ts:
import { describe, it} from "bun:test";
import { file } from "bun";
import { testOracleProgramExecution } from "@seda-protocol/dev-tools"
describe("data request execution", () => {
it("should run MyDataRequest", async () => {
const wasmBinary = await file("target/wasm32-wasip1/release-wasm/oracle-program.wasm").arrayBuffer();
// Locally executes the Data Request
const vmResult = await testOracleProgramExecution(
Buffer.from(wasmBinary),
// This program doesn't have any inputs
Buffer.from(""),
);
console.log(vmResult.stdout);
console.error(vmResult.stderr);
});
});
Testing the Data Request
Running the test will compile the binary and execute the test file, showing the output of the API formatted in JSON.
$ bun run test
Outputs:
bun test v1.2.5 (013fdddc)
tests/index.test.ts:
Response: [...]
β data request execution > should run MyDataRequest [1102.00ms]
Parsing JSON Responses
To make your Oracle Program more useful, you can parse the JSON response and work with its properties. You can use the serde crate to deserialize API responses into custom Rust structs.
Letβs modify our example:
use seda_sdk_rs::{http_fetch, log, oracle_program, Process};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct Color {
name: String,
}
#[derive(Serialize, Deserialize)]
struct PokemonSpecies {
id: u32,
name: String,
color: Color,
is_legendary: bool,
}
#[oracle_program]
impl MyDataRequest {
fn execute() {
let response = http_fetch("https://pokeapi.co/api/v2/pokemon-species/mewtwo", None);
if !response.is_ok() {
Process::error("Could not fetch API endpoint".as_bytes());
return;
}
let species = serde_json::from_slice::<PokemonSpecies>(&response.bytes).unwrap();
log!(
"Pokemon: {} (ID: {}), Color: {}, Legendary: {}",
species.name,
species.id,
species.color.name,
species.is_legendary
);
}
fn tally() {
panic!("Not implemented");
}
}
Running the previous test again now outputs:
bun test v1.2.5 (013fdddc)
tests/index.test.ts:
Pokemon: mewtwo (ID: 150), Color: purple, Legendary: true
β data request execution > should run MyDataRequest [723.00ms]
Now you can call any open API you want and process the data as needed.
HTTP Fetch: POST
The SEDA SDK supports POST, PATCH, PUT, and other HTTP methods via HttpFetchOptions. You can attach headers and a request body β useful for working with GraphQL APIs or file uploads (e.g., IPFS).
Example sending JSON via POST:
use std::collections::BTreeMap;
use seda_sdk_rs::{
bytes::{Bytes, ToBytes},
elog, http_fetch, log, oracle_program, HttpFetchMethod, HttpFetchOptions, Process,
};
use serde_json::json;
#[oracle_program]
impl MyDataRequest {
fn execute() {
let query_body = json!({
"key": "value_test"
});
let mut headers: BTreeMap<String, String> = BTreeMap::default();
headers.insert("content-type".to_string(), "application/json".to_string());
let body: Bytes = query_body.to_string().to_bytes();
let response = http_fetch(
"https://httpbin.org/post",
Some(HttpFetchOptions {
method: HttpFetchMethod::Post,
headers,
body: Some(body),
}),
);
if !response.is_ok() {
elog!("Error: {}", String::from_utf8_lossy(&response.bytes));
Process::error("Could not fetch API endpoint".as_bytes());
return;
}
log!("Success: {}", String::from_utf8(response.bytes).unwrap());
}
fn tally() {
panic!("Not implemented");
}
}
Running the test will give you the response of the POST request: