Give 20% off, earn 20% back on every song you share Get your link β†’
Commercial beta

The Ditty City API

Order a personalized song, its matching e-card and its lyrics from your own software, and get back a page you can send to a customer. Built for the systems that already know whose birthday it is: CRMs, loyalty and benefits platforms, retailers bundling a gift with an order.

Getting access

Keys are issued by hand while the API is in beta, so tell us what you are building and we will set you up with a key, a monthly limit and a commercial-use licence. There is no self-serve signup yet, and no charge for a trial key.

Request an API key

How it works

Writing and singing a song takes a few minutes, so the API is asynchronous throughout. You post a brief and get an id immediately; you poll that id until its status is ready. Every response is JSON, including every error.

POST /v1/ditties            -> 202  { id, status: "pending",  share_url }
GET  /v1/ditties/{id}       -> 200  { id, status: "processing" }
GET  /v1/ditties/{id}       -> 200  { id, status: "ready", song: { title, lyrics } }

The share_url is the product: a page carrying the card, the player and the lyrics. It exists from the moment the ditty does, so you can store it against a customer record straight away β€” it starts playing once the status is ready.

That link is unlisted and not indexed. It is a private page for the person the song is about, not a public gallery entry, so nothing about your customer is published anywhere by ordering one.

Authentication

A bearer token on every request. Keys start with dck_live_ and are shown to you once, when they are issued β€” we store only a hash, so we cannot recover one for you. Tell us and we will revoke it and issue another.

curl https://dittycity.com/v1/me \
  -H "Authorization: Bearer dck_live_YOUR_KEY"

Ordering a ditty

Only recipient is required, but the song is written from what you tell us, so the more specific about is, the better the lyrics. A habit with a time of day on it beats an adjective.

curl -X POST https://dittycity.com/v1/ditties \
  -H "Authorization: Bearer dck_live_YOUR_KEY" \
  -H "Idempotency-Key: order-48213" \
  -H "Content-Type: application/json" \
  -d '{
    "recipient": "Sarah",
    "relationship": "sister",
    "occasion": "birthday",
    "about": "runs by the canal every morning before work, makes terrible puns, still has the blue mug with the chip in it",
    "style": "upbeat folk",
    "voice": "female",
    "sender": "Tom",
    "message": "Happy birthday from your favourite brother"
  }'
FieldNotes
recipientRequired. Who the song is about.
relationshipTheir relationship to the sender: sister, colleague, grandad.
occasionbirthday, anniversary, thank you, new baby, and so on.
aboutThe details the lyrics are written from. Concrete beats abstract.
styleA musical direction: upbeat folk, gentle piano ballad, 90s pop.
voicemale or female.
senderWho it is from.
messageThe message written inside the card.
notify_emailOptional. We email this address when the ditty is ready.

Idempotency

An Idempotency-Key header is required on every create, because a create spends money. Send any unique string per logical order β€” your own order id works well β€” and send the same one again if you retry. A repeat returns the original ditty with an Idempotency-Replayed: true header, and never makes a second song.

Limits

Each account has a monthly ditty quota and a per-minute request limit; both are set when your key is issued, and GET /v1/me always tells you where you stand. The quota is counted from ditties actually created and resets on the 1st of each calendar month, UTC. A ditty that fails to render does not count against it.

Endpoints

MethodPathWhat it does
POST/v1/dittiesOrder a ditty. Returns 202 and an id straight away.
GET/v1/ditties/{id}Fetch one, with its status and, once ready, its song and lyrics.
GET/v1/dittiesList yours, newest first. Takes limit and offset.
GET/v1/meYour account, quota and rate limit. Costs nothing; use it to check a key works.

Errors

Always the same shape, so you can write your handling once.

{ "error": { "type": "quota_exceeded", "message": "Monthly quota reached: 500 of 500 ...", "param": null } }
typeStatusMeans
authentication_error401Missing, unknown or revoked key.
permission_error403The account is suspended.
invalid_request400The brief or a header was not accepted. Look at param.
not_found404No ditty with that id on your account.
idempotency_conflict409That Idempotency-Key was already used with a different brief.
quota_exceeded429Monthly quota reached. Resets on the 1st, UTC.
rate_limit429Too many requests this minute.
api_error500Our fault. Nothing is charged; retry.

Rights and licensing

You get a commercial-use licence for the songs, cards and lyrics your account creates, which is what lets you sell them on or include them in a paid product. We licence use rather than assign copyright, because raw AI output is not copyrightable in the US and we will not pretend otherwise. The exact terms come with your key.

Songs are composed with a licensed AI music engine. We do not imitate real artists or clone anyone's voice.

Tell us what you are building

We will come back with a key, a sensible monthly limit and the licence terms. If it is a good fit we will build the bits you are missing.

Request an API key