Delivery accounts
Your organization has its own SFTP endpoint (see Catalog.sftpHost). A delivery account is a login on that endpoint, issued to one of your senders — a label or a distributor. Senders are not //SCHEMA users; they have no console access, only the account.
Accounts authenticate with SSH keys, a password, or both. Keys are recommended: an account created without a password cannot sign in until you add a key. Changes to passwords and keys take effect on the sender's next connection.
- querydeliveryAccounts
- querydeliveryAccountKeys
- mutationissueDeliveryAccount
- mutationresetDeliveryPassword
- mutationrevokeDeliveryAccount
- mutationaddDeliveryKey
- mutationrevokeDeliveryKey
- mutationsetSftpHost
The DeliveryAccount object#
An SFTP login issued to one of your senders. Never includes a secret.
Attributes
deliveryAccountPkInt!Unique identifier.usernameString!The SFTP login name.displayNameString!Who the account is for, e.g.Lanternfish Records.hasPasswordBoolean!Whether the account has a password.keyCountInt!Live SSH keys.0with no password means the account cannot sign in yet.createdAtDateTime!When it was issued.- Approximately when something last arrived on it.
- When access was withdrawn, or
null.
The DeliveryKey object#
An SSH public key authorized on a delivery account, identified by fingerprint.
Attributes
The IssueDeliveryAccountInput input object#
An SFTP account to issue.
Fields
- The login. 3–32 characters: a lowercase letter, then
a–z,0–9,_or-. Unique on your endpoint. - Who it is for, e.g.
Coastline Sound. catalogPkIntThe catalog its deliveries land in. Must belong to your organization. Defaults to the caller's catalog.withPasswordBooleanGenerate a password. Defaults tofalse— key-only.
List delivery accounts#
Every SFTP login your organization has issued, newest first, including revoked ones.
Arguments
None.
Returns
A list of DeliveryAccount objects.
query {
deliveryAccounts {
deliveryAccountPk
username
displayName
hasPassword
keyCount
lastSeenAt
revokedAt
}
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "query {\n deliveryAccounts {\n deliveryAccountPk\n username\n displayName\n hasPassword\n keyCount\n lastSeenAt\n revokedAt\n }\n}"
}
EOFconst res = await fetch("https://api.schema.fm/graphql", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SCHEMA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
query: `
query {
deliveryAccounts {
deliveryAccountPk
username
displayName
hasPassword
keyCount
lastSeenAt
revokedAt
}
}
`,
}),
});
const { data, errors } = await res.json();{
"data": {
"deliveryAccounts": [
{
"deliveryAccountPk": 64,
"username": "lanternfish",
"displayName": "Lanternfish Records",
"hasPassword": false,
"keyCount": 2,
"lastSeenAt": "2026-09-17T08:51:40.221903+00:00",
"revokedAt": null
}
]
}
}List an account's keys#
The public keys authorized on one delivery account, by fingerprint. An account that is not yours returns an empty list.
Arguments
- The delivery account.
Returns
A list of DeliveryKey objects.
query {
deliveryAccountKeys(deliveryAccountPk: 64) {
deliveryAccountKeyPk
fingerprint
createdAt
revokedAt
}
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "query {\n deliveryAccountKeys(deliveryAccountPk: 64) {\n deliveryAccountKeyPk\n fingerprint\n createdAt\n revokedAt\n }\n}"
}
EOFconst res = await fetch("https://api.schema.fm/graphql", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SCHEMA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
query: `
query {
deliveryAccountKeys(deliveryAccountPk: 64) {
deliveryAccountKeyPk
fingerprint
createdAt
revokedAt
}
}
`,
}),
});
const { data, errors } = await res.json();{
"data": {
"deliveryAccountKeys": [
{
"deliveryAccountKeyPk": 118,
"fingerprint": "SHA256:q1v0mZcX9y5b3kR2nTwL8dPfHgJ4sA6eU7oIcBxYzQk",
"createdAt": "2026-06-02T14:10:33.500112+00:00",
"revokedAt": null
}
]
}
}Issue a delivery account#
Create an SFTP login on your endpoint. By default the account has no
password and cannot sign in until you
add a key. Pass withPassword: true
to generate a password, returned once.
Arguments
- The account to issue.
Show child parameters
- The login. 3–32 characters: a lowercase letter, then
a–z,0–9,_or-. Unique on your endpoint. - Who it is for, e.g.
Coastline Sound. catalogPkIntThe catalog its deliveries land in. Must belong to your organization. Defaults to the caller's catalog.withPasswordBooleanGenerate a password. Defaults tofalse— key-only.
Returns
An IssuedAccount.
mutation {
issueDeliveryAccount(
input: { username: "coastline", displayName: "Coastline Sound", withPassword: true }
) {
deliveryAccountPk
username
password
}
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "mutation {\n issueDeliveryAccount(\n input: { username: \"coastline\", displayName: \"Coastline Sound\", withPassword: true }\n ) {\n deliveryAccountPk\n username\n password\n }\n}"
}
EOFconst res = await fetch("https://api.schema.fm/graphql", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SCHEMA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
query: `
mutation {
issueDeliveryAccount(
input: { username: "coastline", displayName: "Coastline Sound", withPassword: true }
) {
deliveryAccountPk
username
password
}
}
`,
}),
});
const { data, errors } = await res.json();{
"data": {
"issueDeliveryAccount": {
"deliveryAccountPk": 71,
"username": "coastline",
"password": "C9HWT-R2QV8-MZE4K-J6DXS"
}
}
}Reset a delivery password#
Replace an account's password with a generated one. The old password stops working immediately; the new one is returned once.
Arguments
- The delivery account.
Returns
The new password.
mutation {
resetDeliveryPassword(deliveryAccountPk: 71)
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "mutation {\n resetDeliveryPassword(deliveryAccountPk: 71)\n}"
}
EOFconst res = await fetch("https://api.schema.fm/graphql", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SCHEMA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
query: `
mutation {
resetDeliveryPassword(deliveryAccountPk: 71)
}
`,
}),
});
const { data, errors } = await res.json();{
"data": {
"resetDeliveryPassword": "QM4TX-E7VRB-2NK9W-5GHAP"
}
}Revoke a delivery account#
Withdraw an account's access. It stays listed with revokedAt set,
and what it delivered keeps its history. Revoking twice keeps the
first timestamp.
Arguments
- The delivery account.
Returns
true on success.
mutation {
revokeDeliveryAccount(deliveryAccountPk: 71)
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "mutation {\n revokeDeliveryAccount(deliveryAccountPk: 71)\n}"
}
EOFconst res = await fetch("https://api.schema.fm/graphql", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SCHEMA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
query: `
mutation {
revokeDeliveryAccount(deliveryAccountPk: 71)
}
`,
}),
});
const { data, errors } = await res.json();{
"data": {
"revokeDeliveryAccount": true
}
}Add a delivery key#
Authorise an SSH public key on an account. Several keys can be live at once, which makes rotation gapless: add the new key, confirm the sender can connect, then revoke the old one.
Arguments
- The delivery account.
- One
authorized_keysline from the sender, e.g.ssh-ed25519 AAAAC3Nza… ops@lanternfish.
Returns
The new DeliveryKey.
mutation AddKey($key: String!) {
addDeliveryKey(deliveryAccountPk: 64, publicKey: $key) {
deliveryAccountKeyPk
fingerprint
}
}{
"key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHk3b2l0Z0N6c1l4b3dQZ2pQb0VlQ3ZkR2Z0T2xY ops@lanternfish"
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "mutation AddKey($key: String!) {\n addDeliveryKey(deliveryAccountPk: 64, publicKey: $key) {\n deliveryAccountKeyPk\n fingerprint\n }\n}",
"variables": {
"key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHk3b2l0Z0N6c1l4b3dQZ2pQb0VlQ3ZkR2Z0T2xY ops@lanternfish"
}
}
EOFconst res = await fetch("https://api.schema.fm/graphql", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SCHEMA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
query: `
mutation AddKey($key: String!) {
addDeliveryKey(deliveryAccountPk: 64, publicKey: $key) {
deliveryAccountKeyPk
fingerprint
}
}
`,
variables: {
"key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHk3b2l0Z0N6c1l4b3dQZ2pQb0VlQ3ZkR2Z0T2xY ops@lanternfish"
},
}),
});
const { data, errors } = await res.json();{
"data": {
"addDeliveryKey": {
"deliveryAccountKeyPk": 131,
"fingerprint": "SHA256:7GmU2cQkV1xYp9sLbT3rNfWd8hKzE4aJ6oXiRyCvB0M"
}
}
}Revoke a delivery key#
Withdraw one key. Other keys on the account keep working.
Arguments
- The key to revoke.
Returns
true on success.
mutation {
revokeDeliveryKey(deliveryAccountKeyPk: 118)
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "mutation {\n revokeDeliveryKey(deliveryAccountKeyPk: 118)\n}"
}
EOFconst res = await fetch("https://api.schema.fm/graphql", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SCHEMA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
query: `
mutation {
revokeDeliveryKey(deliveryAccountKeyPk: 118)
}
`,
}),
});
const { data, errors } = await res.json();{
"data": {
"revokeDeliveryKey": true
}
}Set the SFTP hostname#
Record your organization's SFTP hostname, e.g.
halcyon.ftp.schema.fm. This records what senders should connect
to; it does not itself provision DNS. Pass null to clear it.
Arguments
hostStringA bare hostname — no scheme, no port. Lowercased. Must not be in use by another organization.
Returns
Your organization's DeliveryAccount list, unchanged.
mutation {
setSftpHost(host: "halcyon.ftp.schema.fm") {
username
}
}curl https://api.schema.fm/graphql \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'EOF'
{
"query": "mutation {\n setSftpHost(host: \"halcyon.ftp.schema.fm\") {\n username\n }\n}"
}
EOFconst res = await fetch("https://api.schema.fm/graphql", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SCHEMA_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
query: `
mutation {
setSftpHost(host: "halcyon.ftp.schema.fm") {
username
}
}
`,
}),
});
const { data, errors } = await res.json();{
"data": {
"setSftpHost": [
{ "username": "lanternfish" },
{ "username": "coastline" }
]
}
}