Worldcoin

World ID

Verifying Proofs via API

This section describes how to verify proofs via the Developer Portal API.

You must first pass the proof to your backend when verifying proofs via the API. The user can manipulate information in the frontend, so you the proof must be verified in a trusted environment.

Our backend should receive the proof, merkle_root, nullifier_hash, and credential_type from IDKit, as well as the same action and signal as were input into IDKit, and send it to the Developer Portal API for verification. The Developer Portal API will return a 200 response if the proof is valid, and a 400 response with extra error detail if the proof is invalid. We then pass the success or error messages back to our frontend after performing our own backend actions.

pages/api/verify.ts

export type VerifyReply = {
  code: string;
  detail?: string;
};

export default function handler(req: NextApiRequest, res: NextApiResponse<VerifyReply>) {
  const reqBody = {
    merkle_root: req.body.merkle_root,
    nullifier_hash: req.body.nullifier_hash,
    proof: req.body.proof,
    credential_type: req.body.credential_type,
    action: req.body.action, // or get this from environment variables,
    signal: req.body.signal ?? "", // if we don't have a signal, use the empty string
  };
  fetch(`https://developer.worldcoin.org/api/v1/verify/${process.env.NEXT_PUBLIC_WLD_APP_ID}`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(reqBody), 
  }).then((verifyRes) => {
    verifyRes.json().then((wldResponse) => {
      if (verifyRes.status == 200) {
        // this is where you should perform backend actions based on the verified credential
        // i.e. setting a user as "verified" in a database
        res.status(verifyRes.status).send({ code: "success" });
      } else {
        // return the error code and detail from the World ID /verify endpoint to our frontend
        res.status(verifyRes.status).send({ 
          code: wldResponse.code, 
          detail: wldResponse.detail 
        });
      }
    });
  });
}

Post-Verification

If handleVerify is does not throw an error, the user will see a success state and the onSuccess callback will be called when the modal is closed. The onSuccess callback should redirect a user to a success page, or perform any other actions you want to take after a user has been verified.

pages/index.tsx

const onSuccess = (result: ISuccessResult) => {
  // This is where you should perform frontend actions once a user has been verified
  window.alert(`Successfully verified with World ID!
    Your nullifier hash is: ` + result.nullifier_hash);
};

For more information on configuration, see the IDKit and Cloud API reference pages.