Introduction to Few and Far Minting: API Docs

Few and Far (aka FnF) Protocol
Few and Far Protocol
9 min readJan 19, 2023

This introduction documentation encompasses the basic usage and features of the Few and Far Minting API version 1.2.

The API is a basic RESTful API requiring an API key for authentication and an associated wallet generated by Few and Far for purposes of funding blockchain transactions (i.e. paying for gas and storage) without direct blockchain integration.

By utilizing our minting API you can bypass the need for direct on-chain communication and drastically reduce development time and the need for expertise on a given blockchain.

Basic Mechanics

Once business formalities have been completed your development team will be provided with an API key to access our API toolset.

An “integration wallet” for the given blockchain will be created by our team for purposes of funding your off-chain minting requests.

When an API request is made to mint via our REST interface an on-chain call is then made and the minting fee shall be debited directly from the “integration wallet”

Note: It’s imperative that the integration wallet has gas (tokens) to facilitate minting, no gas = no mint.

Authorization

All API requests require an API token to be sent in the HTTP request header as seen below. (an API key shall be provided to you by Few and Far)

Authorization: Api-Key xxxxxxxxxxxxxxxxxxxxxxxxxxx

Errors

Any 4xx-level response will contain a “message” property in the response body containing more information about what went wrong.

NFT Contract Deployment

The Few and Far NFT specification allows for deployment of multiple collections within a single contract. A contract can be thought of as a business logic & permissions container for any number of related NFT Collections.

Contracts are currently deployed manually by the Few and Far team, though we do plan to provide tools to deploy and manage contracts via API in the near future.

Deploying a new contract is a fast and easy process; contact your Few and Far representative if you wish to deploy a contract, and we will provide you with its UUID once it has been deployed so that you can utilize the API to create NFT Collections and mint NFTs.

Collection Creation Life Cycle

Creating a Collection consists of three steps:

First: Creating a Collection Draft (occurs off-chain)

Second: Attaching assets (media & metadata files) to your Collection Draft

Third: Finalizing your Collection Draft (this creates the Collection on-chain)

We will explore each of these steps now, as well as endpoints for minting NFTs and updating your collections.

For more information on types, see Referenced Types section below.

  1. Creating a Collection Draft

POST https://fewfar.com/api/v1/collection-draft

Content-type: application/json

Request Body

contract_uuid (required; type string)

The contract that this collection will be deployed to:

title (required; type string; max length 256)

description(required; type string; max length 1024)

nft_title_separator(optional; type string; max length 16; defaults to “: ”)

public_mint_config(optional; type PublicMintConfig)

private_mint_config(optional; type PrivateMintConfig)

private_mint_accounts(optional; type NearAccountId[])

  • These are “allowlisted” accounts that can participate in the private mint.

bypass_mint_fee_accounts(optional; type NearAccountId[])

initial_royalties(optional; type Royalties)

  • Distribution of mint fee. Cannot total more than 95% (5% Few and Far initial royalty will be added before minting)

ongoing_royalties(optional; type Royalties)

  • Royalties for secondary sales. Cannot total more than 100%.

allow_approvals(optional; type bool)

  • If false, an NFT owner cannot give approval to a 3rd party account (e.g. marketplace contract) to transfer the token on their behalf.

approvals_allowed_accounts(optional; type NearAccountId[])

  • If present, listed accounts are the only accounts that can be given approval by an NFT owner to transfer the token on their behalf.

approvals_denied_accounts(optional; type NearAccountId[])

  • If present, listed accounts are the only accounts that cannot be given approval by an NFT owner to transfer the token on their behalf.

allow_transfersIf present, listed accounts are the only accounts that cannot be given approval by an NFT owner to transfer the token on their behalf.

  • If false, an NFT owner cannot transfer their NFT to a new owner (calls to nft_transfer, nft_transfer_call and nft_transfer_payout will panic with a useful error message).

transfers_denied_accounts ((optional; type NearAccountId[])

  • If present, listed accounts are the only accounts that NFT cannot be transferred to. This could be used by the collection owner to prohibit use of escrow marketplaces that skirt royalty payments.
  • Response (201) Body (Collection Draft:
  • A Collection Draftobject (see “Referenced Types” section for details)

Request Body Example

{
"contract_uuid": "8860a24d-fe5f-45d2-aab1-4d1c8f05702d",
"title": "My Collection",
"description": "This is a great collection!",
"nft_title_separator": " - ",
"public_mint_config": {
"price": 10,
"starts_at": 1672645203707,
"limit_per_account": 1
},
"private_mint_config": {
"price": 5.5,
"starts_at": 1672645203707,
"ends_at": 1672645749473,
"limit_per_account": 1,
"limit_total": 100
},
“private_mint_accounts”: [“whitelisted-account.near”],
"initial_royalties": {
"myaccount.near": 90,
"mycollaborator.near": 5
},
"ongoing_royalties": {"myaccount.near": 5},
"bypass_mint_fee_accounts": ["myaccount.near"]
}

Get a Collection Draft:

You can retrieve a Collection Draft by passing its UUID in the following GET request:

GET

https://testnet.fewfar.com/api/v1/collection-draft/{collection_draft_uuid}

2. Attaching Assets to your Collection Draft (i.e. bulk upload)

POST

https://testnet.fewfar.com/api/v1/collection-draft/{collection-draft-uuid}/asset-bulk

Content-type: multipart/form-data

Maximum request body size: 100MB

Maximum size per file: 1MB

Request Body: FormData containing parts as follows:

  • Asset files (media files for NFTs that will be minted in this collection)
    -These parts should be named “asset_file”
  • Reference/Metadata JSON files
    -
    These parts should be named “reference_file”
    -Each Reference file should correspond to one asset file (these associations are made in the assets_detail form part)
    -Each Reference file should follow the OpenSea Metadata Standard
  • Assets Detail (string)
    -JSON-stringified array of AssetDetail objects, each representing one NFT asset and its optional corresponding JSON metadata. Each AssetDetail object contains the following properties:
    asset_filename (required; string)
    -NB: An asset_subtitle file with this name MUST be present in the form data, or 400 response will be returned.
    -asset_subtitle (optional; string)
    — The title of individual NFTs in this collection will be formatted as collection_title + nft_title_separator + asset_subtitle, e.g. “My Collection: Gold Edition” where “My Collection” is the collection_title, “: ”is the nft_title_separator and “Gold Edition” is the asset_subtitle.
    — NB: The following values can be referenced in asset_subtitle and will be inserted into the NFT title at view time:

$ASSET_ID (the ID of the asset, commonly used for generative collections that are minted randomly)

$TOKEN_NUM (the number of this token in the sequential order of minting, starting at 1. E.g. the 2nd token minted in a collection would have a TOKEN_NUM of 2.)

$TOTAL_NUM (the total number of copies for this collection)

  • reference_filename(optional; string)
    — If present, a reference subtitlefile with this name MUST be present in the form data
    copies(required; integer)
    -This part should be named “assets_detail”
    -Only one “assets_detail” part should be provided in the data form

Response Success (201) Body (CollectionDraftAsset[]):

  • An array of CollectionDraftAsset objects (see “Referenced Types” section for details)

assets_detailstring example:


'[{"asset_filename":"0.png","copies":10},{"asset_filename":"1.png","referen
ce_filename":"1.json","copies":10,"asset_subtitle":"Gold"}]'

A collection created with this assets_detail string would contain 20 copies total. 10 copies would use asset file 0.png with no JSON and no NFT subtitle, and 10 copies would use asset file 1.png with 1.json reference file and an NFT subtitle of “Gold”.

cURL Request Example:

curl — request POST \

-url https://testnet.fewfar.com/api/v1/collection-draft/{YOUR_COLLECTION_DRAFT_UUID}/asset-bulk \

-header ‘Authorization: Api-Key {YOUR_API_KEY}’ \

-header ‘Content-type: multipart/form-data’ \form ‘asset_file=@/Users/username/path/to/asset/file.png’ \

-form ‘asset_file=@/Users/username/path/to/asset/file.png’ \

-form ‘assets_detail=”[{\”asset_filename\”:\”file.png\”,\”reference_filename\”:\”file.json\”,\”copies\”:10}]”’ \

— form ‘reference_file=@/Users/username/path/to/reference/file.json’

3. Finalizing your Collection Draft (creating the on-chain collection)

  • POST https://testnet.fewfar.com/api/v1/collection-draft/{collection-draft-uuid/finalize
  • NB: A successful call to this endpoint will use funds from your integration wallet to mint to the blockchain.
  • Request Body: None
  • Response Success (201) Body:
    -
    message (string — “success” if action was successful)
    -ipfs_result (IpfsResult — see “Referenced Types” section below)
    -contract_address (string)
    -near_collection (Collection, as defined in FnF-007 Specification docs)

Contains collection_id (int) property, which is the blockchain ID for the collection and is used within the NFT contract. It is not the same as the collection’s UUID (collection_uuid), which should be used in Few and Far API requests.

This ID can be used if you wish to prompt users through a direct mint flow using a client-side NEAR wallet integration, rather than an API call. You can direct the user to call nft_mint on your contract, and pass this collection_id as “collection_id”. See “End User (non-API) Minting” section below for more information.

  • collection_uuid (string — UUID for collection, used in Few and Far API requests)
  • tx_results (NearTransactionResult[] — see “Reference Types” section)
    -Contains the result of the collection creation transaction.

Get a Collection:

You can retrieve a Collection by passing its UUID in the following GET request:

GET https://testnet.fewfar.com/api/v1/collection/{collection_uuid}

Minting an NFT for a Collection

The minting request is made via the following API endpoint with a collection UUID that identifies the target collection for the mint.

POST https://testnet.fewfar.com/api/v1/collection/{collection_uuid}/mint

Content-type: application/json

Request Body:

  • message(string — “success” if action was successful)
  • token (Token[] — as per FNF-007 Specification)
  • tx_results(NearTransactionResult[] — see “Reference Types” section)
    -Contains a single NearTransactionResults (for the mint transaction)

Example Request Body:

A JSON payload is to be sent in the request body via an HTTP POST method as found below.

{
"receiver_addresses": ["user.near","6ea381017765a0958577fd063a3a359b75075617e880db4c24939e54cbd1b2ac"]
}

Example Request Body:

{
"message": "success",
"tokens": [...],
"tx_results": [{...}],
}

End-User (non-API) Minting

If you wish for your users to mint NFTs directly without an API call, utilize a NEAR wallet client-side library to make an nft_mint function call to the contract address for your collection and pass collection_id integer as its singular argument.

From there a user will be able to sign a transaction utilizing their NEAR wallet of choice (assuming that a public mint has been configured, or user has been added to a private mint whitelist). The contract will mint the NFT to the method caller’s account.

Example JS Contract Call

await wallet.callMethod({
contractId,
method: "nft_mint",
args: {
collection_id: 1
},
gas: ONE_HUNDRED_TGAS,
deposit: MINT_FEE,
});

Updating a Collection Draft

This endpoint allows you to update a Collection Draft that has not yet been finalized.

PUT

https://testnet.fewfar.com/api/v1/collection-draft/{collection_draft_uuid}

Content-type: application/json

Request Body:

  • title (optional; type string; max length 256)
  • description (optional; type string; max length 1024)
  • nft_title_separator (optional; type string; max length 16; defaults to “: ”)
  • public_mint_config (optional; type PublicMintConfig)
  • private_mint_config (optional; type PrivateMintConfig)
  • private_mint_accounts (optional; type NearAccountId[])
  • bypass_mint_fee_accounts (optional; type NearAccountId[])
  • initial_royalties (optional; type Royalties)
  • ongoing_royalties (optional; type Royalties)
  • allow_approvals (optional; type bool)
  • approvals_allowed_accounts (optional; type NearAccountId[])
  • approvals_denied_accounts (optional; type NearAccountId[])
  • allow_transfers (optional; type bool)
  • transfers_denied_accounts (optional; type NearAccountId[])

Response Success (200) Body:

  • Updated CollectionDraft object (see “Referenced Types” section for details)

Example Request Body:

A JSON payload is to be sent in the request body via an HTTP POST method as found below.

{
"description": “An Updated Description”
}

Updating a Collection (on-chain)

This endpoint allows you to update a Collection that has already been created on-chain.

PUT https://testnet.fewfar.com/api/v1/collection/{collection_uuid}

Content-type: application/json

Request Body:

  • title (optional; type string; max length 256)
  • description (optional; type string; max length 1024)
  • nft_title_separator (optional; type string; max length 16; defaults to “: ”)
  • public_mint_config (optional; type PublicMintConfig)
  • private_mint_config (optional; type PrivateMintConfig)
  • private_mint_accounts (optional; type NearAccountId[])
  • bypass_mint_fee_accounts (optional; type NearAccountId[])
  • initial_royalties (optional; type Royalties)
  • ongoing_royalties (optional; type Royalties)
  • allow_approvals (optional; type bool)
  • approvals_allowed_accounts (optional; type NearAccountId[])
  • approvals_denied_accounts (optional; type NearAccountId[])
  • allow_transfers (optional; type bool)
  • transfers_denied_accounts (optional; type NearAccountId[])

Response Success (200) Body:

  • Updated Collection object (see “Referenced Types” section for details)

Example Request Body:

A JSON payload is to be sent in the request body via an HTTP POST method as found below.

{
"description": “An Updated Description”
}

Referenced Types:

Timestamp: int # 13-digit millisecond UNIX timestamp

NearAccountId: string # Named or Implicit NEAR account ID

PublicMintConfig: {
# PublicMintConfig defines the configuration for a public mint, where minters are not required to be whitelisted.
price: float # public mint price of NFT, in $NEAR
starts_at: Timestamp
ends_at?: Timestamp
limit_per_account?: int # if present, a single account won’t be allowed to mint more than this limit
}

`

Royalties: Record<string, float> # mapping of NEAR account IDs to royalty percentages

CollectionDraft: {
uuid: string # use this to perform further actions on your ContractDraft
title: string
description: string
assets: CollectionDraftAsset[]
nft_title_separator: string
public_mint_config: PublicMintConfig | null
private_mint_config: PrivateMintConfig | null
private_mint_accounts: NearAccountId[]
initial_royalties: Royalties
ongoing_royalties: Royalties | null
bypass_mint_fee_accounts: NearAccountId[]
allow_approvals: bool
approvals_allowed_accounts: NearAccountId[]
approvals_denied_accounts: NearAccountId[]
allow_transfers: bool
transfers_denied_accounts: NearAccountId[]
created: Timestamp
updated: Timestamp
}
CollectionDraftAsset: {
uuid: string
copies: int
asset_filename: string
asset_subtitle: string
reference_filename: string | null
created: Timestamp
updated: Timestamp
}
IpfsResult: {
cid: string # cid for IPFS directory containing all assets for this collection
file_urls: Record<string, string> # mapping of filenames to IPFS URLs
upload_hashes: IpfsUploadHashRecord[]
}

NearTransactionResult: see https://docs.near.org/concepts/basics/transactions/overview#transaction-status

Collection: {
uuid: string
name: string
description: string | null
public_mint_config: PublicMintConfig | null
private_mint_config: PrivateMintConfig | null
created: int
is_verified: bool
}

Further endpoints available soon:

  • Endpoint for “simple” (non-bulk) asset upload
  • Endpoints to deploy and manage contracts

To learn more about Few and Far’s API solutions, reach out to us on the following application form. And, join our developer community on Discord!

--

--

Few and Far (aka FnF) Protocol
Few and Far Protocol

Facilitating NFT/Web3 experiences, Few and Far is a one-stop destination for NFT trading, tooling, rewards, and more—visit https://fewandfar.xyz/.