# Schema Creation

## Understanding What We Need

The first step to creating a successful schema is understanding exactly what data your application needs. Let's say, for our application, we want to store two things:

* contractDetails: a string of text, corresponding to what Bob is signing
* signer: an address, corresponding to Bob's account

Note that the attester's address is automatically recorded in any attestation, so we do not need to store this in our schema.

## Creating the Schema

Now that we know what we want to store, we will create a schema on Sign Protocol. We can accomplish this in two ways: first, we can use the [Schema Builder](https://app.sign.global/create-schema). This is perfect for non-coders or setting up a schema quickly, rather than performing the action through code. Second, we can create it by directly interfacing with Sign Protocol's Smart Contract or using the NPM SDK.

The first step is to name your schema, add a description, and choose where to store attestation data. In this tutorial, we will store data on-chain using the Base Sepolia Testnet. Once you choose your configuration, continue to the next step.

{% hint style="warning" %}
NOTE: If you select a data storage option that is not directly on-chain (such as Arweave/IPFS), your schema will require [Hybrid Attestations](https://github.com/EthSign/sign-protocol-docs/blob/main/for-builders/getting-started/advanced-topics/hybrid-attestations.md). Our SDK will handle this for you, but if you are interacting directly with Sign Protocol smart contracts, ensure that you are passing in an encoded Content ID (CID) as `data` when creating a hybrid attestation.
{% endhint %}

### Schema Builder

<figure><img src="/files/oOfBSkfk2ff9A3yyfjZv" alt=""><figcaption><p>Schema Builder Metadata</p></figcaption></figure>

The next step is to create the schema's data structure. As stated earlier, we will create two fields: `contractDetails` and `signer`. The Schema Builder allows you to enter fields in a user-friendly UI or manually edit the JSON data structure (click "Input Raw Data"). Once you have entered your schema data structure fields, continue to the next step.

<figure><img src="/files/0VsvdoKXqUJlFHbylknr" alt=""><figcaption><p>Schema Builder Data Structure</p></figcaption></figure>

When creating a schema, you can designate an additional smart contract address that will be called whenever an event occurs (attestation created, revoked, etc). This can be useful for taking payments or reverting transactions (when some verification fails, i.e. whitelist), but it is outside the scope of this tutorial, so we will leave the field blank for now. We will leave the attestation as non-revocable: Alice cannot make mistakes. Once you have completed this step, press "Create Schema".

<figure><img src="/files/u2QmcPfPAF6X7s02qHf0" alt=""><figcaption><p>Schema Builder Final Details</p></figcaption></figure>

Success! You have successfully created your schema. Click "View Schema" to go to your schema's page.

<figure><img src="/files/NvXc6mV5N1b9nCuhuIvk" alt=""><figcaption><p>Schema Created</p></figcaption></figure>

### NPM SDK

Install the [SDK](#npm-sdk) into your project. Create a SignProtocolClient to make calls that write to the blockchain. The private key field is optional if you are operating from the frontend as the SDK will attempt to use `window.ethereum` if no private key is provided for signing transactions. If you use the SDK from a Node backend, you must provide a private key to make write calls to the blockchain.

{% hint style="warning" %}
NOTE: The `account` variable is marked as optional. If it is not provided, the SDK will use the provider from `window.ethereum` by default to derive an account. If a provider from `window.ethereum` cannot be located when an account is not provided, calls to the SDK will fail.
{% endhint %}

{% hint style="warning" %}
NOTE: You must provide an API key when initializing your SignClient to create offchain attestations. This key is optional for onchain attestations. You can generate a key [here](https://developer.sign.global/). For more information, see [Installation](/for-builders/index-1/npm-sdk/installation.md).
{% endhint %}

```typescript
const { SignProtocolClient, SpMode, EvmChains } = require("@ethsign/sp-sdk");
const { privateKeyToAccount } = require("viem/accounts");

const privateKey = "0x...";
const client = new SignProtocolClient(SpMode.OnChain, {
  chain: EvmChains.baseSepolia,
  account: privateKeyToAccount(privateKey), // Optional, depending on environment
  apiKey: 'xxx', // Optional for onchain, required for offchain
});
```

Next, you will need to create the schema we described above.

```typescript
const res = await client.createSchema({
  name: "SDK Test",
  data: [
    { name: "contractDetails", type: "string" },
    { name: "signer", type: "address" },
  ],
});
```

This will return information from the transaction, including the schema ID and transaction hash. For example, `res` may look like the following:

```json
{
  "schemaId": "0x34",
  "txHash": "0x..."
}
```

Now that you have created your schema, continue to the next page to create an attestation using this schema.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.sign.global/for-builders/getting-started/tutorials/building-a-simple-notary-platform/schema-creation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
