Developer API
A simple REST API that lets you pull your students, performances, practice stats, awards, and more into any website or app you build.
Log in to MyConcertos, go to Profile → Manage API Keys, and click Create API Key. Give it a name, select which student it's for, and choose which data scopes to enable.
One key = one student
Every API key is scoped to a single student for security. If you have multiple children or students, create a separate key for each one you want to expose. If a key is ever compromised, only one student's data is at risk.
Important:
Your API key is shown only once when created. Copy it immediately and store it somewhere safe. If you lose it, revoke the old key and create a new one.
Pass your API key in the Authorization header as a Bearer token. All responses are JSON.
# List your students curl -H "Authorization: Bearer mc_your_key_here" \ https://myconcertos.com/api/v1/students
Every response wraps data in a { "data": ... } object. Here's a quick JavaScript example for fetching upcoming performances:
const res = await fetch(
"https://myconcertos.com/api/v1/performances?upcoming=true",
{
headers: {
"Authorization": "Bearer mc_your_key_here"
}
}
);
const { data } = await res.json();
// data is an array of performances
data.forEach(perf => {
console.log(perf.title, perf.date, perf.venue);
});All API requests require a valid API key passed in the Authorization header:
Authorization: Bearer mc_your_key_here
Every API key is scoped to a single student. A key can only access the data belonging to the student it was created for — never multiple students, even if you have several children or a full studio roster. This ensures that a compromised key has minimal impact.
Each key also has scopes that control which endpoints it can access. You choose scopes when creating the key. Available scopes:
studentsperformancespracticeawardsensemblesrepertoirerecitalsEach API key is limited to 100 requests per minute. Rate limit info is included in every response header:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 97
X-RateLimit-Reset: 1712345678
If you exceed the limit, you'll receive a 429 Too Many Requests response. Wait until the reset timestamp before retrying.
All API endpoints include permissive CORS headers, so you can call the API directly from browser-side JavaScript on any domain. No proxy needed.
Security note: Your API key will be visible in client-side code. API keys are read-only and scoped to your own data, so this is safe for personal and studio websites. If you need tighter security, call the API from your server instead.
Base URL: https://myconcertos.com/api/v1
/api/v1/studentsscope: studentsGet the student this API key is scoped to, with their instruments.
Example Response
{
"data": {
"id": "abc123",
"firstName": "Gustas",
"lastName": "Kish",
"bio": "Violinist since age 5...",
"instruments": [
{
"name": "Violin",
"isPrimary": true,
"startDate": "2019-09-01"
},
{
"name": "Piano",
"isPrimary": false,
"startDate": "2023-01-15"
}
]
}
}/api/v1/students/:id/repertoirescope: repertoireGet a student's repertoire — every piece they've studied.
Query Parameters
status"current" (still working on), "completed" (date_ready set), or omit for allExample Response
{
"data": [
{
"id": "piece123",
"title": "Concerto No. 5 in A minor",
"composer": "Henri Vieuxtemps",
"arranger": null,
"difficulty": "Advanced",
"dateStarted": "2025-09-01",
"dateReady": "2026-02-15",
"performedPublicly": true
}
]
}/api/v1/students/:id/practicescope: practiceGet practice statistics and individual sessions for a student.
Query Parameters
daysNumber of days to look back (default: 30, max: 365)Example Response
{
"data": {
"summary": {
"days": 30,
"totalSessions": 47,
"totalMinutes": 1820,
"daysActive": 28,
"currentStreak": 12,
"averageRating": 3.8
},
"sessions": [
{
"date": "2026-04-06",
"durationMins": 45,
"rating": 4,
"focusAreas": ["scales", "etudes"],
"instrument": "Violin"
}
]
}
}/api/v1/students/:id/awardsscope: awardsGet a student's competition awards and achievements.
Example Response
{
"data": [
{
"id": "award123",
"title": "MSBOA Solo & Ensemble",
"competitionName": "MSBOA District 5",
"date": "2026-02-08",
"level": "STATE",
"placement": "Division I Rating"
}
]
}/api/v1/students/:id/ensemblesscope: ensemblesGet a student's ensemble memberships (orchestras, chamber groups, etc.) with current season info.
Example Response
{
"data": [
{
"id": "ens123",
"name": "OYO Philharmonic Orchestra",
"type": "ORCHESTRA",
"director": "Jane Smith",
"venue": "Hawk Theatre",
"city": "Farmington Hills",
"state": "MI",
"seasons": [
{
"name": "2025-2026 Season",
"startDate": "2025-09-01",
"endDate": "2026-06-15",
"recurrenceDays": "SAT",
"startTime": "09:00",
"endTime": "12:00"
}
]
}
]
}/api/v1/performancesscope: performancesGet performances for all students accessible by your API key.
Query Parameters
upcoming"true" for future events, "false" for past, or omit for alllimitMax results to return (default: 50, max: 100)Example Response
{
"data": [
{
"id": "perf123",
"title": "OHMI Concert",
"venue": "OHMI Recital Hall",
"city": null,
"state": null,
"date": "2025-05-19",
"ensembleType": "ORCHESTRA",
"description": null,
"youtubeUrl": null,
"students": [
{
"role": "Section Violin II",
"student": {
"id": "abc123",
"firstName": "Gustas",
"lastName": "Kish"
}
}
],
"repertoire": [
{
"piece": {
"title": "Symphony No. 5",
"composer": "Beethoven"
}
}
]
}
]
}/api/v1/recitalsscope: recitalsGet studio recitals. Requires a teacher/studio API key.
Query Parameters
upcoming"true" for future events, "false" for past, or omit for alllimitMax results to return (default: 50, max: 100)Example Response
{
"data": [
{
"id": "rec123",
"title": "Spring Studio Recital",
"date": "2026-05-15",
"time": "14:00",
"venue": "Community Music Center",
"description": "Annual spring recital",
"performers": [
{
"pieceTitle": "Concerto in A minor",
"composer": "Vivaldi",
"sortOrder": 1,
"student": {
"id": "abc123",
"firstName": "Gustas",
"lastName": "Kish"
}
}
]
}
]
}All errors return a JSON object with an error message:
{ "error": "Invalid API key" }| Status | Meaning |
|---|---|
| 200 | Success |
| 401 | Missing, invalid, revoked, or expired API key |
| 403 | API key missing required scope for this endpoint |
| 404 | Student or resource not found (or not accessible by your key) |
| 429 | Rate limit exceeded — wait and retry |
| 500 | Server error — try again or contact us |
Here's a complete example of building a performance calendar on your own website using the MyConcertos API. This fetches all performances and renders them as a list.
<div id="calendar"></div>
<script>
const API_KEY = "mc_your_key_here";
const BASE = "https://myconcertos.com/api/v1";
async function loadCalendar() {
const res = await fetch(BASE + "/performances?limit=100", {
headers: { "Authorization": "Bearer " + API_KEY }
});
const { data } = await res.json();
const html = data.map(perf => {
const date = new Date(perf.date).toLocaleDateString("en-US", {
month: "long", day: "numeric", year: "numeric"
});
const students = perf.students
.map(s => s.student.firstName)
.join(", ");
return `
<div class="event">
<div class="event-date">${date}</div>
<h3>${perf.title}</h3>
<p>${[perf.venue, perf.city, perf.state]
.filter(Boolean).join(", ")}</p>
<p>Performers: ${students}</p>
${perf.youtubeUrl
? `<a href="${perf.youtubeUrl}">Watch</a>`
: ""}
</div>
`;
}).join("");
document.getElementById("calendar").innerHTML = html;
}
loadCalendar();
</script>Show off a student's practice streak on their personal website.
<div id="practice-widget"></div>
<script>
const API_KEY = "mc_your_key_here";
const STUDENT_ID = "your_student_id";
const BASE = "https://myconcertos.com/api/v1";
async function loadPractice() {
const res = await fetch(
BASE + "/students/" + STUDENT_ID + "/practice?days=30",
{ headers: { "Authorization": "Bearer " + API_KEY } }
);
const { data } = await res.json();
const s = data.summary;
document.getElementById("practice-widget").innerHTML = `
<div class="streak-card">
<h3>🔥 ${s.currentStreak} Day Streak!</h3>
<p>${s.totalMinutes} minutes practiced this month</p>
<p>${s.daysActive} of ${s.days} days active</p>
</div>
`;
}
loadPractice();
</script>Log in to create your first API key and start building.
Get Started