Developer API

Build with your MyConcertos data.

A simple REST API that lets you pull your students, performances, practice stats, awards, and more into any website or app you build.

Getting Started

1

Create an API Key

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.

2

Make Your First Request

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
3

Use the Data

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);
});

Authentication

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:

studentsperformancespracticeawardsensemblesrepertoirerecitals

Rate Limits

Each 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.

CORS

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.

Endpoints

Base URL: https://myconcertos.com/api/v1

GET/api/v1/studentsscope: students

Get 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"
      }
    ]
  }
}
GET/api/v1/students/:id/repertoirescope: repertoire

Get a student's repertoire — every piece they've studied.

Query Parameters

status"current" (still working on), "completed" (date_ready set), or omit for all

Example 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
    }
  ]
}
GET/api/v1/students/:id/practicescope: practice

Get 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"
      }
    ]
  }
}
GET/api/v1/students/:id/awardsscope: awards

Get 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"
    }
  ]
}
GET/api/v1/students/:id/ensemblesscope: ensembles

Get 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"
        }
      ]
    }
  ]
}
GET/api/v1/performancesscope: performances

Get performances for all students accessible by your API key.

Query Parameters

upcoming"true" for future events, "false" for past, or omit for all
limitMax 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"
          }
        }
      ]
    }
  ]
}
GET/api/v1/recitalsscope: recitals

Get studio recitals. Requires a teacher/studio API key.

Query Parameters

upcoming"true" for future events, "false" for past, or omit for all
limitMax 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"
          }
        }
      ]
    }
  ]
}

Error Handling

All errors return a JSON object with an error message:

{ "error": "Invalid API key" }
StatusMeaning
200Success
401Missing, invalid, revoked, or expired API key
403API key missing required scope for this endpoint
404Student or resource not found (or not accessible by your key)
429Rate limit exceeded — wait and retry
500Server error — try again or contact us

Example: Performance Calendar

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>

Example: Practice Streak Widget

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>

Ready to build?

Log in to create your first API key and start building.

Get Started