> ## Documentation Index
> Fetch the complete documentation index at: https://docs.etherscan.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Verify with the API

> Verify a deployed smart contract programmatically using the Etherscan API, on any supported chain with one key.

Verifying a contract publishes its source code on the Etherscan-run explorer for that chain, so anyone can read it and confirm it matches the bytecode deployed on chain. You can verify from the explorer's [verify page](https://etherscan.io/verifyContract) in the browser, or programmatically through the API. This guide covers the API: submit the source, get a request ID, and poll for the result.

New to the API? Start with [Make your first call](/make-your-first-call).

<Tip>
  One request verifies on every chain, just switch the `chainid`. For example, set `chainid=42161` to verify a contract deployed on Arbitrum. See [Supported chains](/supported-chains) for the full list.
</Tip>

## What you need

Verification succeeds only when the source you submit reproduces the exact bytecode on chain. Before you start, gather these, in the order the request expects them:

* **Contract address (`contractaddress`):** where the contract is deployed, with the `0x` prefix.
* **Source code (`sourceCode`):** the exact code that was deployed, as a single file or a Standard JSON input.
* **Contract name (`contractname`):** the name of the contract to verify, with its path when needed, such as `contracts/MyToken.sol:MyToken`.
* **Compiler version (`compilerversion`):** the full version string, such as `v0.8.28+commit.7893614a`. See the [supported list](https://etherscan.io/solcversions).
* **Optimization settings (`optimizationUsed`, `runs`):** whether optimization was on and the number of runs. These must match the deployment.
* **Constructor arguments (`constructorArguments`):** the ABI-encoded arguments, in hex, if your contract used a constructor. Leave empty otherwise.
* **EVM version (`evmVersion`):** the target EVM version, or the compiler `default`.
* **License type (`licenseType`):** the [license](https://etherscan.io/contract-license-types) to publish with the code, such as `3` for MIT.

A mismatch in any of these is the usual reason verification fails. See [Common verification errors](/contract-verification/common-verification-errors) if it does.

## Choose a source format

Set `codeformat` to match how you submit the source:

* **`solidity-standard-json-input`:** the compiler's Standard JSON input. It carries the source, imports, and every compiler setting in one object, so `optimizationUsed`, `runs`, and `evmVersion` do not need to be sent separately. Use this for any contract with imports (such as OpenZeppelin) or non-default settings. Most build tools can output it.
* **`solidity-single-file`:** one flattened `.sol` file with no external imports. With this format the compiler settings are not embedded, so you send `optimizationUsed` and `runs` as separate fields (per the endpoint's field notes, `optimizationUsed` is required for single-file submissions).

Standard JSON input is the more reliable choice, since the settings travel with the source instead of being restated by hand.

## Verify your contract

<Steps>
  <Step title="Submit the source code">
    Send a `POST` to the `verifysourcecode` action. The `chainid` in the URL selects the network, so use the `chainid` of the chain your contract is deployed to. The example uses Standard JSON input, with the fields in the order the endpoint lists them.

    ```bash theme={null}
    curl --request POST \
      --url 'https://api.etherscan.io/v2/api?chainid=1&module=contract&action=verifysourcecode' \
      --data-urlencode 'apikey=YourApiKey' \
      --data-urlencode 'contractaddress=0xYourContractAddress' \
      --data-urlencode 'sourceCode={"language":"Solidity","sources":{...},"settings":{...}}' \
      --data-urlencode 'contractname=contracts/MyToken.sol:MyToken' \
      --data-urlencode 'compilerversion=v0.8.28+commit.7893614a' \
      --data-urlencode 'codeformat=solidity-standard-json-input' \
      --data-urlencode 'constructorArguments=' \
      --data-urlencode 'licenseType=3'
    ```

    For `solidity-single-file`, set `codeformat=solidity-single-file`, put the flattened source in `sourceCode`, and add `optimizationUsed` and `runs` (they follow `codeformat`, before `constructorArguments`, in the field order).

    A successful submission returns a `result` containing a GUID. This is your request ID, not a confirmation. Keep it for the next step.

    ```json theme={null}
    {
      "status": "1",
      "message": "OK",
      "result": "a7lpxkm9kpcpicx7daftmjifrfhiuhf5vqqnawhkfhzfrcpnxj"
    }
    ```

    <Note>
      Verifying on one chain's explorer does not verify the contract on any other. Repeat this flow with the matching `chainid` for each chain the contract is deployed to.
    </Note>
  </Step>

  <Step title="Check the verification status">
    Pass the GUID to the `checkverifystatus` action to check the result. Verification is queued, so the request may still be processing when you first check: call it again until the `result` resolves.

    ```bash theme={null}
    curl --request GET \
      --url 'https://api.etherscan.io/v2/api?chainid=1&module=contract&action=checkverifystatus&guid=a7lpxkm9kpcpicx7daftmjifrfhiuhf5vqqnawhkfhzfrcpnxj&apikey=YourApiKey'
    ```

    The `result` field reports the outcome. On success it reads `Pass - Verified`.

    ```json theme={null}
    {
      "status": "1",
      "message": "OK",
      "result": "Pass - Verified"
    }
    ```

    If verification does not succeed, `result` returns the reason. Correct the mismatched input and submit again.
  </Step>

  <Step title="Confirm the verified source">
    Once the status reads `Pass - Verified`, a green verified checkmark appears on the Contract tab of the contract's page on the explorer, showing the contract is verified. You can also read the published source back with `getsourcecode`.

    ```bash theme={null}
    curl --request GET \
      --url 'https://api.etherscan.io/v2/api?chainid=1&module=contract&action=getsourcecode&address=0xYourContractAddress&apikey=YourApiKey'
    ```
  </Step>
</Steps>

## Other contract types

The same submit-and-poll flow applies, with a different action for each type:

| Contract type | Action                                                                                                                                                |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| Vyper         | [`verifysourcecode` (Vyper)](/api-reference/endpoint/verifyvyper)                                                                                     |
| zkSync        | [`verifysourcecode` (zkSync)](/api-reference/endpoint/verifyzksyncsourcecode)                                                                         |
| Stylus        | [`verifysourcecode` (Stylus)](/api-reference/endpoint/verifystylus)                                                                                   |
| Proxy         | [`verifyproxycontract`](/api-reference/endpoint/verifyproxycontract), then [`checkproxyverification`](/api-reference/endpoint/checkproxyverification) |

## If verification fails

Most failures come from a setting that does not match the deployment: a different compiler version, optimization runs, EVM version, or constructor arguments. Work through [Common verification errors](/contract-verification/common-verification-errors) for the specific message you received.

Prefer to verify from your existing toolchain instead? See [Verify with Hardhat](/contract-verification/verify-with-hardhat), [Verify with Foundry](/contract-verification/verify-with-foundry), or [Verify with Remix](/contract-verification/verify-with-remix).
