This document gives an AI agent (or any programmatic client) enough context to query the Patantara Carnatic music graph database via its public read-only API endpoint.
POST https://patantara.net/api/query
Content-Type: application/json
{
"cypher": "MATCH (m:Musician) RETURN m.name LIMIT 5",
"params": {}
}
cypher (required): A Cypher read query. Writes (CREATE, MERGE, SET, DELETE, REMOVE) are rejected by the database.params (optional): Object of named parameters for parameterized queries (e.g., $name in Cypher maps to {"name": "Tyagaraja"}).{
"results": [
{ "m.name": "Purandara Dasa" },
{ "m.name": "Venkatamakhin" }
],
"count": 2
}
On error:
{ "error": "error message" }
CALL ...) are blocked.People in the Carnatic music tradition — composers, performers, scholars, instrumentalists.
| Property | Type | Notes |
|---|---|---|
name |
String | Always present. Display name (e.g., "Tyagaraja") |
born |
Integer | Birth year (e.g., 1767). Missing for 4 musicians |
died |
Integer | Death year. Present for ~61 musicians |
instrument |
String | Role/instrument (e.g., "Vocal", "Violin", "Veena", "Vocal/Violin") |
Musical compositions in the Carnatic tradition.
| Property | Type | Notes |
|---|---|---|
name |
String | Transliterated name (e.g., "nagumomu ganalEni") |
ragam |
String | Raga of the song (e.g., "AbhEri"). ⚠️ The property is ragam, NOT raga. Using s.raga returns NULL. |
language |
String | "Telugu" or "Sanskrit". Present on ~1251 songs |
Transliteration convention: Capital letters mid-word represent retroflex or long vowels (e.g., "SrI" = Śrī, "rAma" = Rāma), not word boundaries.
Published texts — music treatises, notation compilations, journals.
| Property | Type | Notes |
|---|---|---|
name |
String | Full title (e.g., "Sangita Sampradaya Pradarshini") |
year |
Integer | Year of publication |
Hypernode representing a documented instance of a song being taught from one musician to another.
| Property | Type | Notes |
|---|---|---|
source_url |
String | Citation URL |
source_title |
String | Citation display text |
excerpt |
String | Supporting textual excerpt |
| Relationship | Direction | Meaning |
|---|---|---|
GURU_OF |
Musician → Musician | Teacher → Student |
KNEW |
Musician → Song | Musician performed/recorded this song |
COMPOSED |
Musician — Song | Musician composed this song (undirected — match with -[:COMPOSED]-) |
CONTAINS |
Book → Song | Book includes this song |
AUTHORED |
Musician → Book | Musician wrote/edited this book |
TAUGHT_IN |
Musician → SongTransmission | Teacher side of a song transmission |
LEARNT_IN |
Musician → SongTransmission | Student side of a song transmission |
OF_SONG |
SongTransmission → Song | Song involved in the transmission |
GURU_OF edges carry: source_url, source_title, excerpt, uncertain (boolean).
KNEW edges carry:
- source_url, source_title, excerpt — citation info (present on ~1260 of 2270)
- year (integer) — year of earliest known performance/recording (present on ~703). NULL for book-sourced entries.
CONTAINS edges carry:
- appears_as — how the song name appears in the book's index
- source_url — link to the book/page
- form — e.g., "Notation available", "Sāhitya only"
- serial — index number within the book
COMPOSED is undirected with no properties.
ragam not raga: The song property is ragam. This is the single most common mistake.
COMPOSED is undirected: Always match with -[:COMPOSED]- (no arrow), not -[:COMPOSED]->. Using a directed match will miss half the results due to arbitrary stored direction.
KNEW direction: Always (musician)-[:KNEW]->(song). This is a directed relationship.
Parameterize user input: Use $param syntax with the params field to avoid injection.
Book years are publication years: Useful for temporal queries (e.g., "performed before publication").
KNEW.year: When present, this is the year of the earliest known performance/recording. Not all KNEW edges have this.
| Name | Year |
|---|---|
| Sangita Sarvartha Sara Sangrahamu | 1857 |
| Gayaka Parijatam | 1877 |
| Oriental Music in European Notation | 1893 |
| Gayakalocanam | 1902 |
| Sangita Sampradaya Pradarshini (SSP) | 1904 |
| PrathamAbhyAsa Pustakamu | 1905 |
| Gayakasiddhañjanam II | 1905 |
| Gayakasiddhāñjanam I | 1906 |
| Sangita Kalanidhi | 1912 |
| Gānenduśēkharam | 1912 |
| Dīkshita Kīrtana Prakāśikai | 1936 |
| Dikshita Kirtana Mala (DKM) — Parts 1–15 + 2nd editions | 1941–1979 |
| Journal of the Music Academy 1943 | 1943 |
| Journal of the Music Academy 1947 | 1947 |
The 17 DKM books follow the naming pattern: "Dikshita Kirtana Mala — Part N (YYYY)".
| Composer | Songs |
|---|---|
| Tyagaraja | 687 |
| Muthuswami Dikshitar | 492 |
| Shyama Shastri | 70 |
These three are the "Trinity" of Carnatic music and account for the vast majority of songs.
// All songs in a raga
MATCH (s:Song {ragam: "tODi"}) RETURN s.name, s.ragam
// Find a musician
MATCH (m:Musician) WHERE m.name CONTAINS "Tyagaraja" RETURN m
// Songs by a composer
MATCH (m:Musician {name: "Muthuswami Dikshitar"})-[:COMPOSED]-(s:Song)
RETURN s.name, s.ragam ORDER BY s.ragam
// Books containing a song
MATCH (b:Book)-[c:CONTAINS]->(s:Song {name: "nagumomu ganalEni"})
RETURN b.name, b.year, c.appears_as
// Students of a guru
MATCH (guru:Musician {name: "Tyagaraja"})-[:GURU_OF]->(student:Musician)
RETURN student.name, student.born ORDER BY student.born
// Who performed a song?
MATCH (m:Musician)-[k:KNEW]->(s:Song {name: "nagumomu ganalEni"})
RETURN m.name, k.year ORDER BY k.year
// Guru lineage (variable-length path)
MATCH path = (ancestor:Musician)-[:GURU_OF*1..5]->(descendant:Musician {name: "Ariyakudi Ramanuja Iyengar"})
RETURN [n IN nodes(path) | n.name] AS lineage
// Songs performed before they appeared in any book
MATCH (m:Musician)-[k:KNEW]->(s:Song)<-[:CONTAINS]-(b:Book)
WHERE k.year IS NOT NULL AND k.year < b.year
RETURN DISTINCT s.name, s.ragam, k.year AS performed, min(b.year) AS first_published
ORDER BY performed
// Dikshitar kritis not in any book
MATCH (d:Musician {name: "Muthuswami Dikshitar"})-[:COMPOSED]-(s:Song)
WHERE NOT EXISTS { MATCH (b:Book)-[:CONTAINS]->(s) }
RETURN s.name, s.ragam ORDER BY s.ragam
// Most-performed songs (by number of performers)
MATCH (m:Musician)-[:KNEW]->(s:Song)
RETURN s.name, s.ragam, count(m) AS performers
ORDER BY performers DESC LIMIT 20
// How many Dikshitar kritis were performed before they appeared in a book?
MATCH (d:Musician {name: "Muthuswami Dikshitar"})-[:COMPOSED]-(s:Song)
MATCH (m:Musician)-[k:KNEW]->(s) WHERE k.year IS NOT NULL
MATCH (b:Book)-[:CONTAINS]->(s)
WITH s, min(k.year) AS first_performed, min(b.year) AS first_published
WHERE first_performed < first_published
RETURN count(s) AS count
// Songs in SSP but not in any DKM volume
MATCH (:Book {name: "Sangita Sampradaya Pradarshini"})-[:CONTAINS]->(s:Song)
WHERE NOT EXISTS {
MATCH (b:Book)-[:CONTAINS]->(s)
WHERE b.name STARTS WITH "Dikshita Kirtana Mala"
}
RETURN s.name, s.ragam ORDER BY s.ragam
// Song transmission details
MATCH (teacher:Musician)-[:TAUGHT_IN]->(st:SongTransmission)<-[:LEARNT_IN]-(student:Musician),
(st)-[:OF_SONG]->(s:Song)
RETURN teacher.name, student.name, s.name, st.excerpt
// Pass {"composer": "Tyagaraja", "ragam": "kalyANi"} as params
MATCH (m:Musician {name: $composer})-[:COMPOSED]-(s:Song {ragam: $ragam})
RETURN s.name ORDER BY s.name
curl example:
curl -s -X POST https://patantara.net/api/query \
-H "Content-Type: application/json" \
-d '{
"cypher": "MATCH (m:Musician {name: $composer})-[:COMPOSED]-(s:Song {ragam: $ragam}) RETURN s.name",
"params": {"composer": "Tyagaraja", "ragam": "kalyANi"}
}'