The Flat API allows you to easily extend the abilities of the Flat Platform, with a wide range of use cases including the following: Creating and importing new music scores using MusicXML, MIDI,...
Bring your own key. This API needs your own Flat API key - get one from the provider, add it once below, and the proxy injects it on every call. Your OmniStream plan covers the unified SDK, key storage, and proxy - the provider's own rate limits still apply to your key.
This is a community listing. If you own this API, you can request ownership.
npm install omnistream-sdkimport { OmniClient } from "omnistream-sdk";
const omni = new OmniClient({ token: process.env.OMNI_KEY! });
// One key reaches every API on the marketplace.
const data = await omni.call("flat/listClasses");One install, one key - the same client calls every API on the marketplace.
Filter the classes by state
List the classes available for the current user
Create a new class
Join a class
Get the details of a single class
Update the class
Activate the class
Archive the class
/**
* FlatAPI - generated by OmniStream from Flat API's OpenAPI spec.
* One typed method per endpoint. A single Omni key reaches the API.
*/
const DEFAULT_BASE = "https://grid.skinvaults.online/v1/proxy/flat";
export class FlatAPIError extends Error {
status: number;
code?: string;
constructor(status: number, code: string | undefined, message?: string) {
super(message || `FlatAPI error ${status}`);
this.name = "FlatAPIError";
this.status = status;
this.code = code;
}
}
export interface FlatAPIOptions {
baseUrl?: string;
fetch?: typeof fetch;
timeoutMs?: number;
}
export class FlatAPI {
/** @param token Your OmniStream key (one key for every API). */
constructor(private token: string, private opts: FlatAPIOptions = {}) {
if (!token) throw new Error("FlatAPI: token is required");
}
rateLimit: { remainingMinute?: number; remainingDay?: number } | null = null;
private async _request(method: string, path: string, { params, body }: { params?: Record<string, unknown>; body?: unknown } = {}): Promise<any> {
const f = this.opts.fetch ?? globalThis.fetch;
const url = new URL((this.opts.baseUrl ?? DEFAULT_BASE).replace(/\/+$/, "") + path);
if (params) for (const [k, v] of Object.entries(params)) if (v != null) url.searchParams.set(k, String(v));
const headers: Record<string, string> = { "x-omni-key": this.token };
if (body !== undefined) headers["content-type"] = "application/json";
const res = await f(url, { method, headers, body: body !== undefined ? JSON.stringify(body) : undefined });
this.rateLimit = {
remainingMinute: Number(res.headers.get("x-ratelimit-remaining-minute")) || undefined,
remainingDay: Number(res.headers.get("x-ratelimit-remaining-day")) || undefined,
};
const data = await res.json().catch(() => ({}));
if (!res.ok) throw new FlatAPIError(res.status, data?.error?.code, data?.error?.message);
return data.data ?? data;
}
/** List the classes available for the current user */
listClasses(params: { "state"?: string }): Promise<any> {
return this._request("GET", "/classes", { params });
}
/** Create a new class */
createClass(body: unknown): Promise<any> {
return this._request("POST", "/classes", { body });
}
/** Join a class */
enrollClass(params: { "enrollmentCode": string }): Promise<any> {
return this._request("POST", "/classes/enroll/{enrollmentCode}", { params });
}
/** Get the details of a single class */
getClass(params: { "class": string }): Promise<any> {
return this._request("GET", "/classes/{class}", { params });
}
/** Update the class */
updateClass(body: unknown, params: { "class": string }): Promise<any> {
return this._request("PUT", "/classes/{class}", { body, params });
}
/** Activate the class */
activateClass(params: { "class": string }): Promise<any> {
return this._request("POST", "/classes/{class}/activate", { params });
}
/** Archive the class */
archiveClass(params: { "class": string }): Promise<any> {
return this._request("POST", "/classes/{class}/archive", { params });
}
/** Unarchive the class */
unarchiveClass(params: { "class": string }): Promise<any> {
return this._request("DELETE", "/classes/{class}/archive", { params });
}
/** Assignments listing */
listAssignments(params: { "class": string }): Promise<any> {
return this._request("GET", "/classes/{class}/assignments", { params });
}
/** Assignment creation */
createAssignment(body: unknown, params: { "class": string }): Promise<any> {
return this._request("POST", "/classes/{class}/assignments", { body, params });
}
/** Archive the assignment */
archiveAssignment(params: { "class": string; "assignment": string }): Promise<any> {
return this._request("POST", "/classes/{class}/assignments/{assignment}/archive", { params });
}
/** Unarchive the assignment. */
unarchiveAssignment(params: { "class": string; "assignment": string }): Promise<any> {
return this._request("DELETE", "/classes/{class}/assignments/{assignment}/archive", { params });
}
/** Copy an assignment */
copyAssignment(body: unknown, params: { "class": string; "assignment": string }): Promise<any> {
return this._request("POST", "/classes/{class}/assignments/{assignment}/copy", { body, params });
}
/** List the students' submissions */
getSubmissions(params: { "class": string; "assignment": string }): Promise<any> {
return this._request("GET", "/classes/{class}/assignments/{assignment}/submissions", { params });
}
/** Create or edit a submission */
createSubmission(body: unknown, params: { "class": string; "assignment": string }): Promise<any> {
return this._request("PUT", "/classes/{class}/assignments/{assignment}/submissions", { body, params });
}
/** CSV Grades exports */
exportSubmissionsReviewsAsCsv(params: { "class": string; "assignment": string }): Promise<any> {
return this._request("GET", "/classes/{class}/assignments/{assignment}/submissions/csv", { params });
}
/** Excel Grades exports */
exportSubmissionsReviewsAsExcel(params: { "class": string; "assignment": string }): Promise<any> {
return this._request("GET", "/classes/{class}/assignments/{assignment}/submissions/excel", { params });
}
/** Get a student submission */
getSubmission(params: { "class": string; "assignment": string; "submission": string }): Promise<any> {
return this._request("GET", "/classes/{class}/assignments/{assignment}/submissions/{submission}", { params });
}
/** Edit a submission */
editSubmission(body: unknown, params: { "class": string; "assignment": string; "submission": string }): Promise<any> {
return this._request("PUT", "/classes/{class}/assignments/{assignment}/submissions/{submission}", { body, params });
}
/** Delete a submission */
deleteSubmission(params: { "class": string; "assignment": string; "submission": string; "class": string; "assignment": string; "submission": string }): Promise<any> {
return this._request("DELETE", "/classes/{class}/assignments/{assignment}/submissions/{submission}", { params });
}
/** List the feedback comments of a submission */
getSubmissionComments(params: { "class": string; "assignment": string; "submission": string }): Promise<any> {
return this._request("GET", "/classes/{class}/assignments/{assignment}/submissions/{submission}/comments", { params });
}
/** Add a feedback comment to a submission */
postSubmissionComment(body: unknown, params: { "class": string; "assignment": string; "submission": string }): Promise<any> {
return this._request("POST", "/classes/{class}/assignments/{assignment}/submissions/{submission}/comments", { body, params });
}
/** Update a feedback comment to a submission */
updateSubmissionComment(body: unknown, params: { "class": string; "assignment": string; "submission": string; "comment": string }): Promise<any> {
return this._request("PUT", "/classes/{class}/assignments/{assignment}/submissions/{submission}/comments/{comment}", { body, params });
}
/** Delete a feedback comment to a submission */
deleteSubmissionComment(params: { "class": string; "assignment": string; "submission": string; "comment": string }): Promise<any> {
return this._request("DELETE", "/classes/{class}/assignments/{assignment}/submissions/{submission}/comments/{comment}", { params });
}
/** Get the history of the submission */
getSubmissionHistory(params: { "class": string; "assignment": string; "submission": string }): Promise<any> {
return this._request("GET", "/classes/{class}/assignments/{assignment}/submissions/{submission}/history", { params });
}
/** List the submissions for a student */
listClassStudentSubmissions(params: { "class": string; "user": string }): Promise<any> {
return this._request("GET", "/classes/{class}/students/{user}/submissions", { params });
}
/** Add a user to the class */
addClassUser(params: { "class": string; "user": string }): Promise<any> {
return this._request("PUT", "/classes/{class}/users/{user}", { params });
}
/** Remove a user from the class */
deleteClassUser(params: { "class": string; "user": string }): Promise<any> {
return this._request("DELETE", "/classes/{class}/users/{user}", { params });
}
/** List the collections */
listCollections(params: { "parent"?: string; "sort"?: string; "direction"?: string; "limit"?: number; "next"?: string; "previous"?: string }): Promise<any> {
return this._request("GET", "/collections", { params });
}
/** Create a new collection */
createCollection(body: unknown): Promise<any> {
return this._request("POST", "/collections", { body });
}
/** Get collection details */
getCollection(params: { "collection": string; "sharingKey"?: string }): Promise<any> {
return this._request("GET", "/collections/{collection}", { params });
}
/** Update a collection's metadata */
editCollection(body: unknown, params: { "collection": string }): Promise<any> {
return this._request("PUT", "/collections/{collection}", { body, params });
}
/** Delete the collection */
deleteCollection(params: { "collection": string }): Promise<any> {
return this._request("DELETE", "/collections/{collection}", { params });
}
/** List the scores contained in a collection */
listCollectionScores(params: { "collection": string; "sharingKey"?: string; "sort"?: string; "direction"?: string; "limit"?: number; "next"?: string; "previous"?: string }): Promise<any> {
return this._request("GET", "/collections/{collection}/scores", { params });
}
/** Add a score to the collection */
addScoreToCollection(params: { "collection": string; "score": string; "sharingKey"?: string }): Promise<any> {
return this._request("PUT", "/collections/{collection}/scores/{score}", { params });
}
/** Delete a score from the collection */
deleteScoreFromCollection(params: { "collection": string; "score": string; "sharingKey"?: string }): Promise<any> {
return this._request("DELETE", "/collections/{collection}/scores/{score}", { params });
}
/** Untrash a collection */
untrashCollection(params: { "collection": string }): Promise<any> {
return this._request("POST", "/collections/{collection}/untrash", { params });
}
/** Get group information */
getGroupDetails(params: { "group": string }): Promise<any> {
return this._request("GET", "/groups/{group}", { params });
}
/** List group's scores */
getGroupScores(params: { "group": string; "parent"?: string }): Promise<any> {
return this._request("GET", "/groups/{group}/scores", { params });
}
/** List group's users */
listGroupUsers(params: { "group": string; "source"?: string }): Promise<any> {
return this._request("GET", "/groups/{group}/users", { params });
}
/** Get current user profile */
getAuthenticatedUser(params: { "onlyId"?: boolean }): Promise<any> {
return this._request("GET", "/me", { params });
}
/** List the organization invitations */
listOrganizationInvitations(params: { "role"?: string; "limit"?: number; "next"?: string; "previous"?: string }): Promise<any> {
return this._request("GET", "/organizations/invitations", { params });
}
/** Create a new invitation to join the organization */
createOrganizationInvitation(body: unknown): Promise<any> {
return this._request("POST", "/organizations/invitations", { body });
}
/** Remove an organization invitation */
removeOrganizationInvitation(params: { "invitation": string }): Promise<any> {
return this._request("DELETE", "/organizations/invitations/{invitation}", { params });
}
/** List LTI 1.x credentials */
listLtiCredentials(): Promise<any> {
return this._request("GET", "/organizations/lti/credentials", {});
}
/** Create a new couple of LTI 1.x credentials */
createLtiCredentials(body: unknown): Promise<any> {
return this._request("POST", "/organizations/lti/credentials", { body });
}
/** Revoke LTI 1.x credentials */
revokeLtiCredentials(params: { "credentials": string }): Promise<any> {
return this._request("DELETE", "/organizations/lti/credentials/{credentials}", { params });
}
/** List the organization users */
listOrganizationUsers(params: { "sort"?: string; "direction"?: string; "next"?: string; "previous"?: string; "role"?: unknown[]; "q"?: string; "group"?: unknown[]; "noActiveLicense"?: boolean; "licenseExpirationDate"?: unknown[]; "onlyIds"?: boolean; "limit"?: number }): Promise<any> {
return this._request("GET", "/organizations/users", { params });
}
/** Create a new user account */
createOrganizationUser(body: unknown): Promise<any> {
return this._request("POST", "/organizations/users", { body });
}
/** Count the organization users using the provided filters */
countOrgaUsers(params: { "role"?: unknown[]; "q"?: string; "group"?: unknown[]; "noActiveLicense"?: boolean }): Promise<any> {
return this._request("GET", "/organizations/users/count", { params });
}
/** Update account information */
updateOrganizationUser(body: unknown, params: { "user": string }): Promise<any> {
return this._request("PUT", "/organizations/users/{user}", { body, params });
}
/** Remove an account from Flat */
removeOrganizationUser(params: { "user": string; "convertToIndividual"?: boolean }): Promise<any> {
return this._request("DELETE", "/organizations/users/{user}", { params });
}
/** Create a new score */
createScore(body: unknown): Promise<any> {
return this._request("POST", "/scores", { body });
}
/** Get a score's metadata */
getScore(params: { "score": string; "sharingKey"?: string }): Promise<any> {
return this._request("GET", "/scores/{score}", { params });
}
/** Edit a score's metadata */
editScore(body: unknown, params: { "score": string }): Promise<any> {
return this._request("PUT", "/scores/{score}", { body, params });
}
/** Delete a score */
deleteScore(params: { "score": string; "now"?: boolean }): Promise<any> {
return this._request("DELETE", "/scores/{score}", { params });
}
/** List the collaborators */
getScoreCollaborators(params: { "score": string; "sharingKey"?: string }): Promise<any> {
return this._request("GET", "/scores/{score}/collaborators", { params });
}
/** Add a new collaborator */
addScoreCollaborator(body: unknown, params: { "score": string }): Promise<any> {
return this._request("POST", "/scores/{score}/collaborators", { body, params });
}
/** Get a collaborator */
getScoreCollaborator(params: { "score": string; "collaborator": string; "sharingKey"?: string }): Promise<any> {
return this._request("GET", "/scores/{score}/collaborators/{collaborator}", { params });
}
/** Delete a collaborator */
removeScoreCollaborator(params: { "score": string; "collaborator": string }): Promise<any> {
return this._request("DELETE", "/scores/{score}/collaborators/{collaborator}", { params });
}
/** List comments */
getScoreComments(params: { "score": string; "sharingKey"?: string; "type"?: string; "sort"?: string; "direction"?: string }): Promise<any> {
return this._request("GET", "/scores/{score}/comments", { params });
}
/** Post a new comment */
postScoreComment(body: unknown, params: { "score": string; "sharingKey"?: string }): Promise<any> {
return this._request("POST", "/scores/{score}/comments", { body, params });
}
/** Update an existing comment */
updateScoreComment(body: unknown, params: { "score": string; "comment": string; "sharingKey"?: string }): Promise<any> {
return this._request("PUT", "/scores/{score}/comments/{comment}", { body, params });
}
/** Delete a comment */
deleteScoreComment(params: { "score": string; "comment": string; "sharingKey"?: string }): Promise<any> {
return this._request("DELETE", "/scores/{score}/comments/{comment}", { params });
}
/** Mark the comment as resolved */
markScoreCommentResolved(params: { "score": string; "comment": string; "sharingKey"?: string }): Promise<any> {
return this._request("PUT", "/scores/{score}/comments/{comment}/resolved", { params });
}
/** Mark the comment as unresolved */
markScoreCommentUnresolved(params: { "score": string; "comment": string; "sharingKey"?: string; "sharingKey"?: string }): Promise<any> {
return this._request("DELETE", "/scores/{score}/comments/{comment}/resolved", { params });
}
/** Fork a score */
forkScore(body: unknown, params: { "score": string; "sharingKey"?: string }): Promise<any> {
return this._request("POST", "/scores/{score}/fork", { body, params });
}
/** List the revisions */
getScoreRevisions(params: { "score": string; "sharingKey"?: string }): Promise<any> {
return this._request("GET", "/scores/{score}/revisions", { params });
}
/** Create a new revision */
createScoreRevision(body: unknown, params: { "score": string }): Promise<any> {
return this._request("POST", "/scores/{score}/revisions", { body, params });
}
/** Get a score revision */
getScoreRevision(params: { "score": string; "revision": string; "sharingKey"?: string }): Promise<any> {
return this._request("GET", "/scores/{score}/revisions/{revision}", { params });
}
/** Get a score revision data */
getScoreRevisionData(params: { "score": string; "revision": string; "format": string; "sharingKey"?: string; "parts"?: string; "onlyCached"?: boolean; "url"?: boolean }): Promise<any> {
return this._request("GET", "/scores/{score}/revisions/{revision}/{format}", { params });
}
/** List submissions related to the score */
getScoreSubmissions(params: { "score": string }): Promise<any> {
return this._request("GET", "/scores/{score}/submissions", { params });
}
/** List the audio or video tracks linked to a score */
listScoreTracks(params: { "score": string; "sharingKey"?: string; "assignment"?: string; "listAutoTrack"?: boolean }): Promise<any> {
return this._request("GET", "/scores/{score}/tracks", { params });
}
/** Add a new video or audio track to the score */
addScoreTrack(body: unknown, params: { "score": string }): Promise<any> {
return this._request("POST", "/scores/{score}/tracks", { body, params });
}
/** Retrieve the details of an audio or video track linked to a score */
getScoreTrack(params: { "score": string; "track": string; "sharingKey"?: string }): Promise<any> {
return this._request("GET", "/scores/{score}/tracks/{track}", { params });
}
/** Update an audio or video track linked to a score */
updateScoreTrack(body: unknown, params: { "score": string; "track": string }): Promise<any> {
return this._request("PUT", "/scores/{score}/tracks/{track}", { body, params });
}
/** Remove an audio or video track linked to the score */
deleteScoreTrack(params: { "score": string; "track": string }): Promise<any> {
return this._request("DELETE", "/scores/{score}/tracks/{track}", { params });
}
/** Untrash a score */
untrashScore(params: { "score": string }): Promise<any> {
return this._request("POST", "/scores/{score}/untrash", { params });
}
/** Get a public user profile */
getUser(params: { "user": string }): Promise<any> {
return this._request("GET", "/users/{user}", { params });
}
/** List liked scores */
gerUserLikes(params: { "user": string; "ids"?: boolean }): Promise<any> {
return this._request("GET", "/users/{user}/likes", { params });
}
/** List user's scores */
getUserScores(params: { "user": string; "parent"?: string }): Promise<any> {
return this._request("GET", "/users/{user}/scores", { params });
}
}
export default FlatAPI;
No reviews yet. Be the first to rate this API.
Yes. Flat API uses bearer authentication, so you bring your own key from the provider. You store it once on OmniStream and the proxy injects it into every call, so your code only ever sends your Omni key.
The Flat API allows you to easily extend the abilities of the Flat Platform, with a wide range of use cases including the following: Creating and importing new music scores using MusicXML, MIDI,... It exposes 81 endpoints over GET, POST, PUT, DELETE, including GET /classes, POST /classes, POST /classes/enroll/{enrollmentCode}.
Install the OmniStream SDK for your language and call Flat API through it. The client is generated from this API's OpenAPI spec, so parameters and responses are fully typed, and the same client also calls every other API in the marketplace.
You can start on the free plan. OmniStream charges for the unified SDK, key storage and proxy rather than for Flat API itself, and Flat API's own rate limits still apply to your provider key.
Spotify: Spotify Web API - discover music and podcasts, manage your library, and control playback.
Unarchive the class
Assignments listing
Assignment creation
Archive the assignment
Unarchive the assignment.
Copy an assignment
List the students' submissions
Create or edit a submission
CSV Grades exports
Excel Grades exports
Get a student submission
Edit a submission
Delete a submission
List the feedback comments of a submission
Add a feedback comment to a submission
Update a feedback comment to a submission
Delete a feedback comment to a submission
Get the history of the submission
List the submissions for a student
Add a user to the class
Remove a user from the class
List the collections
Create a new collection
Get collection details
Update a collection's metadata
Delete the collection
List the scores contained in a collection
Add a score to the collection
Delete a score from the collection
Untrash a collection
Get group information
List group's scores
List group's users
Get current user profile
List the organization invitations
Create a new invitation to join the organization
Remove an organization invitation
List LTI 1.x credentials
Create a new couple of LTI 1.x credentials
Revoke LTI 1.x credentials
List the organization users
Create a new user account
Count the organization users using the provided filters
Update account information
Remove an account from Flat
Create a new score
Get a score's metadata
Edit a score's metadata
Delete a score
List the collaborators
Add a new collaborator
Get a collaborator
Delete a collaborator
List comments
Post a new comment
Update an existing comment
Delete a comment
Mark the comment as resolved
Mark the comment as unresolved
Fork a score
List the revisions
Create a new revision
Get a score revision
Get a score revision data
List submissions related to the score
List the audio or video tracks linked to a score
Add a new video or audio track to the score
Retrieve the details of an audio or video track linked to a score
Update an audio or video track linked to a score
Remove an audio or video track linked to the score
Untrash a score
Get a public user profile
List liked scores
List user's scores