It is possible to write applications in the permaweb that can communicate with any internet API or website. By using EXM.deterministicFetch , EXM will execute your fetch petition and create a specific context affiliated to that request. At the time of lazy-evaluating your serverless function, this context will be provided and the output will result deterministically the same to the original output of the EXM execution.


EXM.deterministicFetch follows the same signature as fetch , a Web API implemented in modern browsers for javascript. This means, deterministicFetch is called in the same way you would do with fetch as it is essentially the same at a behavior level but the response object is different than Response .
Read about Fetch API here.
The responses given by deterministicFetch are encapsulated in a special object to EXM that is needed in order to make these requests deterministic inside Arweave.
EXM's response object follows the same structure
interface ExmResponse {
type: string;
url: string;
statusText: string;
status: number;
redirected: boolean;
ok: boolean;
headers: Record<string, string>;
raw: Uint8Array;
asText: () => string;
asJSON: () => any;


export async function handle(state, action) {
const someDeterministicFetch = await EXM.deterministicFetch('');
const jsonResponse = someDeterministicFetch.asJSON();
return {
In the example above, we are deterministically fetching
Which in its nature, returns a JSON response. By doing asJSON() we can transform this response to a javascript object which we then use in the state (, this returns the id found in the JSON object from the url above.