Admin API Reference

The Admin API allows you to programmatically create new Admin proposals.

Requests need to be authenticated with a bearer token, which is negotiated from the Team API Key with the corresponding capability. Refer to the authentication section for info on how to negotiate it.

We recommend you use the defender-admin-client npm package for simplifying interactions with the Admin API.

Proposals Endpoint

The /proposals endpoint is used for creating new Admin action proposals via a POST request. Any actions created this way will have no approvals initially. If the recipient contract of the proposal does not exist, it will be created with the parameters provided.

type Network =
  | 'mainnet'
  | 'ropsten'
  | 'rinkeby'
  | 'kovan'
  | 'goerli'
  | 'xdai'
  | 'sokol'
  | 'fuse'
  | 'bsc'
  | 'bsctest'
  | 'fantom'
  | 'fantomtest'
  | 'moonbase'
  | 'matic'
  | 'mumbai'
  | 'avalanche'
  | 'fuji'
  | 'celo'
  | 'alfajores'
  | 'arbitrum'
  | 'arbitrum-rinkeby';

type Address = string;
type ProposalFunctionInputs = (string | boolean | (string | boolean)[])[];

type ProposalFunctionInputType = {
  name?: string;
  type: string;
  internalType?: string;
  components?: ProposalFunctionInputType[];
}

interface CreateProposalRequest {
  contract: {
    network: Network;
    address: Address;
    name?: string;
    abi?: string;
  };
  title: string;
  description: string;
  type: 'upgrade' | 'custom';
  via?: Address;
  viaType?: 'Gnosis Safe' | 'Gnosis Multisig';
  functionInterface?: { name?: string; inputs?: ProposalFunctionInputType[]; };
  functionInputs?: ProposalFunctionInputs;
  metadata?: {
    newImplementationAddress?: Address;
    proxyAdminAddress?: Address;
    action?: 'pause' | 'unpause';
    operationType?: 'call' | 'delegateCall';
  };
}

Note that the fields via (address of the multisig via which the request is sent), viaType (type of the multisig), functionInterface (ABI definition of the function to call), and functionInputs are required for custom proposals. On the other hand, only metadata.newImplementationAddress is required for upgrade type proposals, since Defender will automatically calculate the remaining fields for you.

An example of an upgrade request:

DATA='{
  "contract": {
    "address": "0x179810822f56b0e79469189741a3fa5f2f9a7631",
    "network": "rinkeby"
  },
  "title": "Upgrade to v2",
  "description": "Upgrading contract to version 2.0",
  "type": "upgrade",
  "metadata": { "newImplementation": "0x3E5e9111Ae8eB78Fe1CC3bb8915d5D461F3Ef9A9" }
}'

curl \
  -X POST \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H "X-Api-Key: $KEY" \
  -H "Authorization: Bearer $TOKEN" \
  -d "$DATA" \
    "https://defender-api.openzeppelin.com/admin/proposals"
The Defender API will only validate that the function inputs are valid with regards to the signature, but it will not validate that the proposal can actually be executed. This means you can create proposals for calling a non-existing function on a contract, or trying to upgrade a non-upgradeable contract. However, you will not be able to approve them afterwards.

Contracts Endpoint

The /contracts endpoint can be used to manage the contracts imported into the Defender Admin dashboard. By issuing a PUT to the endpoint you can create or update a contract given its network and address:

DATA='{
  "address": "0x179810822f56b0e79469189741a3fa5f2f9a7631",
  "network": "rinkeby",
  "name": "My Contract",
  "abi": "..."
}'

curl \
  -X POST \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H "X-Api-Key: $KEY" \
  -H "Authorization: Bearer $TOKEN" \
  -d "$DATA" \
    "https://defender-api.openzeppelin.com/admin/contracts"

You can also issue a GET request to the same endpoint to retrieve a list of all contracts imported.