Appearance
Factory API (/factory)
All routes are prefixed with /factory.
Examples use BASE_URL="https://ebg-tokenizer.u3dev.deno.net" unless your operator provides another origin (HTTP API overview).
- Read-only routes require the deployment to know the factory contract address.
- Write routes require a server-side signer configured by your operator. Clients send JSON only—they do not sign transactions.
Quick reference
| Method | Path | Signer required |
|---|---|---|
POST | /factory/certificates | Yes |
GET | /factory/certificate-count | — |
GET | /factory/certificates | — |
GET | /factory/certificates/:index | — |
GET | /factory/minter-role | — |
GET | /factory/mints | — |
GET | /factory/maximum-mints | — |
POST /factory/roles/grant and POST /factory/roles/revoke are not exposed as live routes.
Minting is not a factory HTTP route. Use POST /certificates/:address/mint (same onchain mint_certificate / CertificateMinted behavior and mint + transaction response).
POST /factory/certificates
Purpose
Deploys a new certificate ERC-721 collection via the factory’s create_certificate (name, symbol, base URI). The HTTP layer maps a nested nft object to those onchain arguments, waits for the transaction, then returns the new contract address and certificate id.
Auth
When API key auth is enabled (overview):
x-api-keyrequired on/factoryroutes.- Master or minter role may call this endpoint; read keys get 403 on
POST. - 401 — missing or unrecognized key.
If API keys are disabled, rely on network controls; the deployment must still be configured for server-side signing, or writes will fail with server errors.
Request
- Headers:
Content-Type: application/json - Optional:
x-api-keywhen auth is enabled.
Body (JSON)
| Field | Type | Required | Notes |
|---|---|---|---|
nft | object | Yes | Maps to name, symbol, base URI |
nft object
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | Also: _name |
symbol | string | Yes | Also: _symbol |
baseUri | string | No | Also: base_uri, _base_uri. Omit or empty for auto metadata base (see Semantics). |
Semantics
- Onchain limits: name up to 25 characters, symbol up to 5, base URI up to 80. Longer values can revert (transaction failure → 500 / 502).
resolvedBaseUriin the success payload is always set: either the computed auto base or the manual URI echoed back.
Automatic base_uri (recommended)
If you omit nft.baseUri (or aliases base_uri / _base_uri) or send an empty string, the service computes _base_uri so onchain tokenURI resolves to the public metadata endpoint (GET /metadata/...):
{publicMetadataOrigin}/metadata/{chainId}/{nextCertificateId}/
publicMetadataOrigin— Configured on the deployment: public HTTPS (or HTTP) origin only, no trailing slash.chainId— 42161 (Arbitrum One), matching the metadata route.nextCertificateId— The collection id assigned to the new certificate (from factory state before the create transaction). The service sequences automatic creates so this id matches the value baked into_base_uri.
The full string must be ≤ 80 characters. If it is too long, the API returns 400.
After mining, the service checks that the new collection id matches the id baked into _base_uri. A mismatch (e.g. races across replicas) returns 500 with a message like certificate id mismatch — retry after coordination.
Multi-replica: automatic mode assumes one concurrent creator per factory unless you add external coordination.
Manual base_uri
If nft.baseUri (or base_uri / _base_uri) is a non-empty string, it is passed through after length validation (≤ 80).
The factory stores certificate details with id, deployed address, and collection name (symbol and base URI are read from the collection contract if needed).
Responses
200 OK — JSON:
json
{
"txHash": "0x…",
"certificateAddress": "0x…",
"certificateId": "0",
"index": "0",
"details": {
"id": "0",
"address": "0x…",
"name": "My Cohort"
},
"resolvedBaseUri": "https://…/metadata/42161/0/"
}Errors
| Status | Situation |
|---|---|
| 400 | Invalid JSON, missing nft, missing name/symbol, base URI too long for onchain field, etc. ({ "message" }) |
| 401 | API key missing or invalid when auth is enabled |
| 403 | Read-only API key used for POST |
| 500 | Certificate id mismatch after create (auto base), signer/RPC issues, reverted transaction |
| 502 | Upstream / configuration failures as surfaced by the service |
Examples
Manual base URI
bash
curl -sS -X POST "$BASE_URL/factory/certificates" \
-H "Content-Type: application/json" \
-H "x-api-key: $MINTER_KEY" \
-d '{
"nft": {
"name": "My Cohort",
"symbol": "CERT",
"baseUri": "https://example.com/meta/"
}
}'Automatic base URI — the deployment supplies a public metadata origin; client omits baseUri:
bash
curl -sS -X POST "$BASE_URL/factory/certificates" \
-H "Content-Type: application/json" \
-H "x-api-key: $MINTER_KEY" \
-d '{
"nft": {
"name": "My Cohort",
"symbol": "CERT"
}
}'GET /factory/certificate-count
Success 200:
json
{ "certificateCount": "3" }GET /factory/certificates
Returns the certificate count and one row per index from onchain certificate details: id, address, name (collection name only).
Success 200:
json
{
"certificateCount": "2",
"certificates": [
{ "id": "0", "address": "0x…", "name": "My Cohort" },
{ "id": "1", "address": "0x…", "name": "Other" }
]
}Empty registry: certificateCount is "0" and certificates is [].
bash
curl -sS "$BASE_URL/factory/certificates"GET /factory/certificates/:index
:index must be a decimal integer. Returns the certificate address and details for that index. 404 if no certificate exists. 400 if index is not an integer.
Success 200:
json
{
"index": "0",
"certificateAddress": "0x…",
"details": {
"id": "0",
"address": "0x…",
"name": "My Cohort"
}
}bash
curl -sS "$BASE_URL/factory/certificates/0"GET /factory/minter-role
Success 200:
json
{ "minterRole": "0x…" }minterRole is a bytes32 (66-char 0x hex).
GET /factory/mints
Success 200:
json
{ "mints": "0" }GET /factory/maximum-mints
Success 200:
json
{ "maximumMints": "1000" }Errors
Route-specific tables above cover POST /factory/certificates. In general, validation issues return 400 with { "message": "…" }; misconfiguration or failed transactions may return 500 or 502. See HTTP API overview — authentication for 401 / 403 when x-api-key is enforced.