# GraphBrainz API Reference ## Endpoint Configuration | Parameter | Environment Variable | Default | |-----------|---------------------|---------| | Path | GRAPHBRAINZ_PATH | / | | Port | PORT | 3000 | | CORS Origin | GRAPHBRAINZ_CORS_ORIGIN | false | | GraphiQL | GRAPHBRAINZ_GRAPHIQL | true (development) | ## Query Types GraphBrainz exposes four primary query entry points: ### 1. Lookup Queries Direct entity retrieval by MusicBrainz ID (MBID). ```graphql type Query { lookup: LookupQuery } type LookupQuery { area(mbid: String!): Area artist(mbid: String!): Artist collection(mbid: String!): Collection event(mbid: String!): Event instrument(mbid: String!): Instrument label(mbid: String!): Label place(mbid: String!): Place recording(mbid: String!): Recording release(mbid: String!): Release releaseGroup(mbid: String!): ReleaseGroup series(mbid: String!): Series url(mbid: String!): URL work(mbid: String!): Work } ``` **Example**: ```graphql { lookup { artist(mbid: "5b11f4ce-a62d-471e-81fc-a69a8278c7da") { name type country lifeSpan { begin end } } } } ``` ### 2. Browse Queries Retrieve entities linked to a parent entity with cursor-based pagination. ```graphql type Query { browse: BrowseQuery } type BrowseQuery { areas( collection: String first: Int after: String ): AreaConnection artists( area: String collection: String recording: String release: String releaseGroup: String work: String first: Int after: String ): ArtistConnection collections( area: String artist: String editor: String event: String label: String place: String recording: String release: String releaseGroup: String work: String first: Int after: String ): CollectionConnection events( area: String artist: String collection: String place: String first: Int after: String ): EventConnection labels( area: String collection: String release: String first: Int after: String ): LabelConnection places( area: String collection: String first: Int after: String ): PlaceConnection recordings( artist: String collection: String release: String first: Int after: String ): RecordingConnection releases( area: String artist: String collection: String label: String recording: String releaseGroup: String track: String trackArtist: String first: Int after: String ): ReleaseConnection releaseGroups( artist: String collection: String release: String first: Int after: String ): ReleaseGroupConnection } ``` **Example**: ```graphql { browse { releases( artist: "5b11f4ce-a62d-471e-81fc-a69a8278c7da" first: 10 ) { edges { node { title date status } } pageInfo { hasNextPage endCursor } totalCount } } } ``` ### 3. Search Queries Lucene-based full-text search across entity types. ```graphql type Query { search: SearchQuery } type SearchQuery { areas(query: String!, first: Int, after: String): AreaConnection artists(query: String!, first: Int, after: String): ArtistConnection events(query: String!, first: Int, after: String): EventConnection instruments(query: String!, first: Int, after: String): InstrumentConnection labels(query: String!, first: Int, after: String): LabelConnection places(query: String!, first: Int, after: String): PlaceConnection recordings(query: String!, first: Int, after: String): RecordingConnection releases(query: String!, first: Int, after: String): ReleaseConnection releaseGroups(query: String!, first: Int, after: String): ReleaseGroupConnection works(query: String!, first: Int, after: String): WorkConnection } ``` **Lucene Query Syntax**: - `artist:"Radiohead"` - Exact phrase match - `artist:Radiohead AND country:GB` - Boolean operators - `artist:Radio*` - Wildcard search - `begin:[1990 TO 2000]` - Range queries - `tag:rock^2 tag:alternative` - Boosting **Example**: ```graphql { search { artists(query: "artist:Radiohead AND country:GB", first: 5) { edges { node { name country type score } } } } } ``` ### 4. Node Query (Relay) Global object identification via Relay-compliant node interface. ```graphql type Query { node(id: ID!): Node } interface Node { id: ID! } ``` **Example**: ```graphql { node(id: "QXJ0aXN0OjViMTFmNGNlLWE2MmQtNDcxZS04MWZjLWE2OWE4Mjc4YzdkYQ==") { ... on Artist { name country } } } ``` ## Entity Types ### Artist ```graphql type Artist implements Node { id: ID! mbid: MBID! name: String sortName: String disambiguation: String type: String typeID: MBID country: String area: Area beginArea: Area endArea: Area lifeSpan: LifeSpan gender: String genderID: MBID ipis: [IPI] isnis: [ISNI] aliases: [Alias] recordings: RecordingConnection releases: ReleaseConnection releaseGroups: ReleaseGroupConnection works: WorkConnection relationships: RelationshipConnection collections: CollectionConnection tags: TagConnection # Extension fields fanArt: FanArtImages mediaWikiImages: [MediaWikiImage] theAudioDB: TheAudioDBArtist } ``` ### Release ```graphql type Release implements Node { id: ID! mbid: MBID! title: String disambiguation: String asin: String status: String statusID: MBID packaging: String packagingID: MBID quality: String date: Date country: String barcode: String artists: [Artist] artistCredit: [ArtistCredit] labels: [ReleaseLabel] media: [Medium] releaseGroup: ReleaseGroup relationships: RelationshipConnection collections: CollectionConnection tags: TagConnection # Extension fields coverArtArchive: CoverArtArchiveRelease } ``` ### Recording ```graphql type Recording implements Node { id: ID! mbid: MBID! title: String disambiguation: String length: Duration video: Boolean isrcs: [ISRC] artists: [Artist] artistCredit: [ArtistCredit] releases: ReleaseConnection relationships: RelationshipConnection collections: CollectionConnection tags: TagConnection } ``` ### ReleaseGroup ```graphql type ReleaseGroup implements Node { id: ID! mbid: MBID! title: String disambiguation: String type: String typeID: MBID primaryType: String primaryTypeID: MBID secondaryTypes: [String] secondaryTypeIDs: [MBID] firstReleaseDate: Date artists: [Artist] artistCredit: [ArtistCredit] releases: ReleaseConnection relationships: RelationshipConnection collections: CollectionConnection tags: TagConnection } ``` ### Area ```graphql type Area implements Node { id: ID! mbid: MBID! name: String sortName: String disambiguation: String type: String typeID: MBID iso31661Codes: [String] iso31662Codes: [String] iso31663Codes: [String] lifeSpan: LifeSpan aliases: [Alias] relationships: RelationshipConnection collections: CollectionConnection tags: TagConnection } ``` ### Label ```graphql type Label implements Node { id: ID! mbid: MBID! name: String sortName: String disambiguation: String type: String typeID: MBID labelCode: Int ipis: [IPI] area: Area lifeSpan: LifeSpan aliases: [Alias] releases: ReleaseConnection relationships: RelationshipConnection collections: CollectionConnection tags: TagConnection } ``` ### Work ```graphql type Work implements Node { id: ID! mbid: MBID! title: String disambiguation: String type: String typeID: MBID language: String languages: [String] iswcs: [ISWC] artists: [Artist] relationships: RelationshipConnection collections: CollectionConnection tags: TagConnection } ``` ### Event ```graphql type Event implements Node { id: ID! mbid: MBID! name: String disambiguation: String type: String typeID: MBID time: String cancelled: Boolean setlist: String lifeSpan: LifeSpan aliases: [Alias] relationships: RelationshipConnection collections: CollectionConnection tags: TagConnection } ``` ### Place ```graphql type Place implements Node { id: ID! mbid: MBID! name: String disambiguation: String type: String typeID: MBID address: String area: Area coordinates: Coordinates lifeSpan: LifeSpan aliases: [Alias] relationships: RelationshipConnection collections: CollectionConnection tags: TagConnection } ``` ### Instrument ```graphql type Instrument implements Node { id: ID! mbid: MBID! name: String disambiguation: String type: String typeID: MBID description: String aliases: [Alias] relationships: RelationshipConnection collections: CollectionConnection tags: TagConnection } ``` ### Series ```graphql type Series implements Node { id: ID! mbid: MBID! name: String disambiguation: String type: String typeID: MBID aliases: [Alias] relationships: RelationshipConnection collections: CollectionConnection tags: TagConnection } ``` ### Collection ```graphql type Collection implements Node { id: ID! mbid: MBID! name: String editor: String type: String typeID: MBID entityType: String areas: AreaConnection artists: ArtistConnection events: EventConnection instruments: InstrumentConnection labels: LabelConnection places: PlaceConnection recordings: RecordingConnection releases: ReleaseConnection releaseGroups: ReleaseGroupConnection series: SeriesConnection works: WorkConnection } ``` ## Relay Connection Types All list fields return Relay-compliant connection types: ```graphql type ArtistConnection { edges: [ArtistEdge] nodes: [Artist] pageInfo: PageInfo! totalCount: Int } type ArtistEdge { node: Artist cursor: String! score: Int # Only present in search results } type PageInfo { hasNextPage: Boolean! hasPreviousPage: Boolean! startCursor: String endCursor: String } ``` ### Pagination - `first: Int` - Number of items to return - `after: String` - Cursor for pagination **Example**: ```graphql { browse { releases(artist: "...", first: 10) { edges { node { title } cursor } pageInfo { hasNextPage endCursor } } } } # Next page { browse { releases(artist: "...", first: 10, after: "Y3Vyc29yOjEw") { edges { node { title } } } } } ``` ### Nodes Shortcut Access nodes directly without edges: ```graphql { browse { releases(artist: "...", first: 10) { nodes { title date } } } } ``` ## Extension Fields ### Cover Art Archive Added to `Release` type: ```graphql type Release { coverArtArchive: CoverArtArchiveRelease } type CoverArtArchiveRelease { front: Boolean back: Boolean artwork: Boolean count: Int release: String images: [CoverArtArchiveImage] } type CoverArtArchiveImage { fileID: String image: String thumbnails: CoverArtArchiveThumbnails front: Boolean back: Boolean types: [String] edit: Int approved: Boolean comment: String } type CoverArtArchiveThumbnails { small: String large: String } ``` **Example**: ```graphql { lookup { release(mbid: "...") { title coverArtArchive { front images { image thumbnails { large } types } } } } } ``` ### fanart.tv Added to `Artist` type: ```graphql type Artist { fanArt: FanArtImages } type FanArtImages { backgrounds: [FanArtImage] banners: [FanArtImage] logos: [FanArtLabelImage] logosHD: [FanArtLabelImage] thumbnails: [FanArtImage] } type FanArtImage { imageID: String url: String likes: Int } type FanArtLabelImage { imageID: String url: String likes: Int color: String } ``` **Configuration**: Requires `FANART_API_KEY` environment variable. **Example**: ```graphql { lookup { artist(mbid: "...") { name fanArt { backgrounds { url likes } logosHD { url color } } } } } ``` ### MediaWiki Added to `Artist` type: ```graphql type Artist { mediaWikiImages: [MediaWikiImage] } type MediaWikiImage { url: String descriptionURL: String title: String user: String size: Int width: Int height: Int canonicalTitle: String objectName: String descriptionShortURL: String metadata: [MediaWikiImageMetadata] } type MediaWikiImageMetadata { name: String value: String } ``` **Example**: ```graphql { lookup { artist(mbid: "...") { name mediaWikiImages { url width height metadata { name value } } } } } ``` ### TheAudioDB Added to `Artist` type: ```graphql type Artist { theAudioDB: TheAudioDBArtist } type TheAudioDBArtist { artistID: String biography: String biographyEN: String memberCount: Int banner: String logo: String thumbnail: String fanArt: [TheAudioDBImage] } type TheAudioDBImage { url: String } ``` **Configuration**: Requires `THEAUDIODB_API_KEY` environment variable. **Example**: ```graphql { lookup { artist(mbid: "...") { name theAudioDB { biographyEN logo fanArt { url } } } } } ``` ## Scalar Types ```graphql scalar MBID # MusicBrainz ID (UUID format) scalar Date # ISO 8601 date (YYYY-MM-DD) scalar Duration # Milliseconds (integer) scalar IPI # Interested Parties Information code scalar ISNI # International Standard Name Identifier scalar ISRC # International Standard Recording Code scalar ISWC # International Standard Musical Work Code ``` ## Authentication Core GraphBrainz API requires no authentication. Extensions may require API keys: | Extension | Environment Variable | Required | |-----------|---------------------|----------| | fanart.tv | FANART_API_KEY | Yes | | TheAudioDB | THEAUDIODB_API_KEY | Yes | | Cover Art Archive | - | No | | MediaWiki | - | No | ## CORS Configuration Enable CORS via environment variable: ```bash GRAPHBRAINZ_CORS_ORIGIN="https://example.com" # or GRAPHBRAINZ_CORS_ORIGIN="*" ``` Default: `false` (CORS disabled) ## GraphiQL Interface Interactive GraphQL IDE enabled by default in development mode. **Configuration**: ```bash GRAPHBRAINZ_GRAPHIQL=true # Enable GRAPHBRAINZ_GRAPHIQL=false # Disable ``` Access at configured path (default: http://localhost:3000/) ## Rate Limits GraphBrainz enforces MusicBrainz API rate limits: - **MusicBrainz**: 5 requests per 5.5 seconds - **Extensions**: 10 requests per second (default) Rate limit errors return HTTP 429 with retry-after header. ## Error Handling GraphQL errors follow standard format: ```json { "errors": [ { "message": "Artist not found", "locations": [{ "line": 2, "column": 3 }], "path": ["lookup", "artist"], "extensions": { "code": "NOT_FOUND", "mbid": "invalid-mbid" } } ], "data": null } ``` Error codes: - `NOT_FOUND` - Entity not found - `INVALID_MBID` - Invalid MusicBrainz ID format - `RATE_LIMIT` - Rate limit exceeded - `NETWORK_ERROR` - Upstream API error - `VALIDATION_ERROR` - Invalid query parameters