Query Api Endpoint?

I’m really confused. I am just trying to query a canister contract from my react app using rest API.

I’m following the docs here: Internet Computer Content Validation Bootstrap

But it isn’t clear how to structure my fetch request. I keep getting 400 code.

Here is how I am calling:

const fetchCanister = async () => {
    const url = 'https://nns.ic0.app/api/v2/canister/tkaa-syaaa-aaaab-aaafq-cai/query';
    const res = await fetch(url, {
        method: 'POST',
        body: {
            "request_type": "query",
            "sender": "<my principal id>",
            "ingress_expiry": 1000,
            "canister_id": "<canister principal id>",
            "method_name": "get_nervous_system_parameters",
            "arg": "()",

    const json = await res.json()
    const result = JSON.stringify(json)

To be fair I am a newbie over my head here and I am positive my principal Id is wrong because I the docs say to use a self-authenticated id I have no clue how to create such a thing or where I would go to get one.

Please help or advice because I have looked everywhere and there’s no actual example of a simple fetch request query of a canister contract.

This is not a valid canister principal. The first batch of letters is only four characters long but should be five.

That’s the thing, there is no “simple fetch” request query of a canister unless the particular canister exposes such a feature. Most of the time, frontend developers use a set of library called agent-js to interact with canisters.

e.g. this isn’t a valid endpoint.

As you mention that you have not yet lots of experience on the IC, maybe I can recommend you to follow / have a look at this quick tutorial. It gives a good idea of how things work and are interconnected. Hope that helps get started.


You are looking at low-level documentation with this link. Instead, you should be using this library: @dfinity/agent - npm

A couple of errors that can already be spotted in your code:

  • invalid principal tkaa-syaaa-aaaab-aaafq-cai
  • url should be https://ic0.app/api/v2/canister/ not https://nns.ic0.app/api/v2/canister/
  • missing CBOR encoding

In the docs that you linked to it says: “Request are POST requests with a CBOR-encoded request body, which consists of a authentication envelope (as per Authentication) and request-specific content as described below.”

Anyway, the agent-js library does all that for you, so don’t worry about fixing those errors. Instead, use the library.

However, the documentation for agent-js tends to show more than you actually need. You don’t need all the authentication part if you’re just doing anonymous queries. I don’t know the link to the simplest documentation for doing this (though I would like to know a link myself).


Agent-js docs are here: https://erxue-5aaaa-aaaab-qaagq-cai.raw.ic0.app/

Otherwise, my first place to go if I don’t know how to do something is the examples repo. Almost every feature is in there in some shape or form.

1 Like

I still don’t find a minimal example that makes a (anonymous) query call in those links.

Yes, I agree discoverability is… ehm… let’s say “not perfect”

The best place to make the first few calls using agent-js is probably this intro page.

Also, I think I found an example how to use agent-js in the examples repo: Query function is defined here (and produced through dfx generate. This file is not hand-written) and used like this.

@kpeacock do you know if we have anything better? Maybe a Coding with Kyle episode?

Thanks for the links.

Curiously this page explains how to create the actor but stops short of actually making the call.

1 Like

Apologies I just copy pasted a mock canister id.

I’ve looked at agent-js but it’s even more confusing. I am trying to build a dashboard that queries canisters for simple information. The dashboard is not running on ICP and is just a basic react app. When looking at agent-js I couldn’t find a simple example in the docs for my use case.

For instance, I know how to interact with a frontend that lives in a canister via DID but how to interact with a canister when the frontend is not connected to ICP in any way and lives on the regular web?

I have installed the package in my app but I’m still unclear on how exactly to make a POST request using it.

I have exactly build this in cycles.watch which happen to be open source. Maybe you can have a look to its code and find exactly what you are looking for ?


I guess you mean when the frontend is not deployed on the IC? If so, you can pass https://ic0.app as host property of the HttpAgent of agent-js. Don’t have that right here but there are few similar question on the forum I think.

1 Like

Thanks you guys are super awesome. I have some rabbit holes to go down now!

1 Like

Generally, I avoid encouraging people from hand-crafting calls using an agent because it’s an awful experience, in my opinion. We’re able to auto-generate an entire interface and pass it to an actor, which gives you the full interface, the arguments, and the return types, which is almost always preferable.

There are better tools for interacting with arbitrary canisters, like ic0 - npm or @infu/icblast - npm, which will fetch the interface for you.

1 Like

We have a “hidden and unapproved” bounty called icSwagger that I think would be really great to have for more traditional web2 devs that want to consume IC services but that don’t want to take the time to learn the agent:

Feedback welcome as we love to get it approved and I think it could really help with onboarding devs who know they’ll be able to get users by publishing a swagger file.

Keep us posted if you have more questions. Have fun :call_me_hand:

@xrkuzd I’m happy to sit down with you and help you get set up. Would you mind explaining your experience trying to figure out what to do, and how you thought about it? This is really useful feedback for us in terms of our documentation!

What I could never find in terms of documentation is a good entry point. Depending on whether you have: browser/node, js/ts, framework/no framework, frontend web2/hosted on IC, local .did file available/not, make query calls/update calls, make anonymous calls/authenticated calls. What is the minimal example in each of those or combinations of those cases?

There is documentation on internetcomputer.org, in examples repo, in blog posts, in videos, but you kind of have to read them to end to figure out what situation they were made for. It would be nice to have a quick-entry matrix.

But maybe the ic0 npm package does it all. I just didn’t know about it until now.

Btw, why would there be any difference between a frontend hosted on web2 vs hosted on IC?

Isn’t it advisable to at least hand-craft a .did file and generate the bindings from it? Otherwise, don’t you end up with generic names like Result_1? I mean for interaction with canisters that you didn’t write yourself.

The intro page, along with the node.js followup that Severin linked to was my best effort at writing a good entry point

As for hand-crafting a .did file, I’m of two minds on it. It can clean things up nicely, but it’s also technically a new language to work in with limited tooling, so it can be a lot to ask of someone who’s just getting started