# Web2Json for Custom API

> Retrieve arbitrary Web2 data.

> For the complete documentation index, see [llms.txt](/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.

Source: https://dev.flare.network/fdc/guides/foundry/web2-json-for-custom-api

The [Web2Json guide](/fdc/guides/foundry/web2-json) demonstrates how the Flare Data Connector can be used to fetch Web2 and store it on the chain. The code for this and other examples is available within the [Flare Foundry starter](https://github.com/flare-foundation/flare-foundry-starter) repository. In this guide, we will see how the `Web2Json` example script within the Flare Foundry starter can be modified to work with custom data and custom contracts. That way, the example code can serve as the base building block for a custom project.

## Necessary modifications[​](#necessary-modifications "Direct link to Necessary modifications")

In order to run on custom data, the example code needs to be modified in four places only. Those are:

1.  The contract within the `src/fdcExample/Web2Json.sol` file.
2.  The attestation request parameters at the top of the `script/fdcExample/Web2Json.s.sol`. In particular the parameters:

-   `apiUrl`
-   `postProcessJq`
-   `abiSignature`

3.  The `DeployContract` script within the `script/fdcExample/Web2Json.s.sol` file.
4.  The `InteractWithContract` contract within the `script/fdcExample/Web2Json.s.sol` file.

## Contract[​](#contract "Direct link to Contract")

The contract within the `src/fdcExample/Web2Json.sol` file should be changed to reflect the project goals. It could be omitted entirely and replaced with multiple files. The only requirement is that at least one contract - the one interacting with FDC - implements a function that accepts an `IWeb2Json.Proof` struct parameter.

## Attestation request parameters[​](#attestation-request-parameters "Direct link to Attestation request parameters")

script/fdcExample/Web2Json.s.sol

```
  // Setting request data  string public apiUrl = "https://swapi.info/api/people/3";  string public httpMethod = "GET";  string public headers = ""; // defaults to Content-Type: application/json  string public queryParams = "{}";  string public body = "{}";  string public postProcessJq =      '{name: .name, height: .height, mass: .mass, numberOfFilms: .films | length, uid: (.url | split(\\"/\\") | .[-1] | . * 1)}';  string public abiSignature =      '{\\"components\\": [{\\"internalType\\": \\"string\\", \\"name\\": \\"name\\", \\"type\\": \\"string\\"},{\\"internalType\\": \\"uint256\\", \\"name\\": \\"height\\", \\"type\\": \\"uint256\\"},{\\"internalType\\": \\"uint256\\", \\"name\\": \\"mass\\", \\"type\\": \\"uint256\\"},{\\"internalType\\": \\"uint256\\", \\"name\\": \\"numberOfFilms\\", \\"type\\": \\"uint256\\"},{\\"internalType\\": \\"uint256\\", \\"name\\": \\"uid\\", \\"type\\": \\"uint256\\"}],\\"name\\": \\"task\\",\\"type\\": \\"tuple\\"}';
```

The attestation request parameters should describe the new Web2 source.

The `apiUrl` is the URL of the API. It can additionally be configured with the `headers`, `queryParams`, and `body` fields. A different `httpMethod` can also be selected.

The `postProcessJq` is the jq-filter that will be applied to the JSON data retrieved from the `apiUrl` API. It rearranges and modifies the input JSON into a new JSON. The `postProcessJq` filter can be workshopped using an online tool, like [The JQ Playground](https://play.jqlang.org).

The `abiSignature` parameter determines how the modified JSON should be represented in Solidity. It is the ABI signature of an appropriate struct.

The easiest way to acquire it is to create a `DataTransportObject` struct with the correct fields within some solidity file. Then, create a public dummy function that accepts a `DataTransportObject` parameter. After running `forge build` (you might need to run `forge clean` first), the contract artifact will be created within the `out/` directory, in the directory that corresponds to the contract with the dummy function. The dummy function can be searched for within the file of its parent contract, and the `abiSignature` read from its `inputs` field.

## Deploy script[​](#deploy-script "Direct link to Deploy script")

script/fdcExample/Web2Json.s.sol

```
contract DeployContract is Script {    function run() external {        uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");        vm.startBroadcast(deployerPrivateKey);        StarWarsCharacterList characterList = new StarWarsCharacterList();        address _address = address(characterList);        vm.stopBroadcast();        Base.writeToFile(            dirPath,            string.concat(attestationTypeName, "_address"),            StringsBase.toHexString(abi.encodePacked(_address)),            true        );    }}
```

The `DeployContract` script should be modified to deploy and verify the new contract. If the contract is deployed and verified by another script, and thus the script will only interact with an existing contract, the script can be omitted.

## Interact with contract script[​](#interact-with-contract-script "Direct link to Interact with contract script")

script/fdcExample/Web2Json.s.sol

```
contract InteractWithContract is Script {    function run() external {        string memory addressString = vm.readLine(            string.concat(dirPath, attestationTypeName, "_address", ".txt")        );        address _address = vm.parseAddress(addressString);        string memory proofString = vm.readLine(            string.concat(dirPath, attestationTypeName, "_proof", ".txt")        );        bytes memory proofBytes = vm.parseBytes(proofString);        IWeb2Json.Proof memory proof = abi.decode(            proofBytes,            (IWeb2Json.Proof)        );        uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");        vm.startBroadcast(deployerPrivateKey);        IStarWarsCharacterList characterList = IStarWarsCharacterList(_address);        characterList.addCharacter(proof);        vm.stopBroadcast();    }}
```

The `InteractWithContract` script should be modified to interact with the new contract. Unless the dApp requires a more intricate interaction with the new contract, only the last few lines should be fundamentally changed. Likely, only the parameter type and the contract functions called should change.
