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.
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"
}'
| Field | Notes |
|---|---|
| recipient | Required. Who the song is about. |
| relationship | Their relationship to the sender: sister, colleague, grandad. |
| occasion | birthday, anniversary, thank you, new baby, and so on. |
| about | The details the lyrics are written from. Concrete beats abstract. |
| style | A musical direction: upbeat folk, gentle piano ballad, 90s pop. |
| voice | male or female. |
| sender | Who it is from. |
| message | The message written inside the card. |
| notify_email | Optional. 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
| Method | Path | What it does |
|---|---|---|
| POST | /v1/ditties | Order 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/ditties | List yours, newest first. Takes limit and offset. |
| GET | /v1/me | Your 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 } }
| type | Status | Means |
|---|---|---|
| authentication_error | 401 | Missing, unknown or revoked key. |
| permission_error | 403 | The account is suspended. |
| invalid_request | 400 | The brief or a header was not accepted. Look at param. |
| not_found | 404 | No ditty with that id on your account. |
| idempotency_conflict | 409 | That Idempotency-Key was already used with a different brief. |
| quota_exceeded | 429 | Monthly quota reached. Resets on the 1st, UTC. |
| rate_limit | 429 | Too many requests this minute. |
| api_error | 500 | Our 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