GameDev Outsourcing Directory API

Aggregate counts and the ranking lists.

GitHub OpenAPI

Operations 3

GET /api/public/v1/statistics Directory-wide aggregate counts #
GET /api/public/v1/rankings List the ranking lists #
GET /api/public/v1/rankings/{slug} Get one ranking list #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/gamedevoutsourcing-com:gamedevoutsourcing-com-directory-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

gamedevoutsourcing-com-directory-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Game Dev Outsourcing Directory API
  version: 1.0.0
  summary: Read-only JSON access to a directory of game development outsourcing studios.
  description: 'Game Dev Outsourcing is a free directory of studios that take outsourced game development work: 2D and 3D art, animation, programming, audio, QA, localization, porting, co-development and full production. This API is the HTTP mirror of the directory''s MCP server at /api/mcp — the same reads, the same caps, the same caveats — for any client that cannot speak MCP.


    What the data is. These are hand-compiled listings, not vetted or certified suppliers. Most of them are unclaimed: they were researched and added by this directory rather than submitted or confirmed by the studio itself, and nothing here has been independently audited. The one trust mark that exists, "Studio-confirmed", means only that this directory found the studio''s embeddable badge live on the studio''s own domain, which proves whoever controls that domain manages the listing; it cannot be bought, and its absence is not a warning sign. Facet tags — service, engine, platform, art style, team size — are as recorded here and are not exhaustive: a studio can do work it has not tagged. Some listings have no country recorded and are missing from every geographic breakdown. Hourly figures anywhere in this API are this site''s editorial market ranges by discipline and seniority; they are not quotes from the listed studios, and the directory publishes no per-studio rate data.


    How lists are ordered. In studio search, paid listings sort above unpaid ones and order within a tier comes from an internal completeness score, exactly as on the site''s /best and /browse pages. Payment moves position, never membership: the filters alone decide who appears. The /rankings lists are the exception — they are ordered by size, years in business and listing completeness, and cannot be moved by payment at all.


    What this API deliberately does not do. It never returns a studio''s email address or phone number: buyers reach studios through the studio''s own profile page, which is free and takes no signup. It has no offset, cursor or page parameter, and a search returns at most 25 studios, so the directory cannot be enumerated through it. Every search does report the true `total` and a `browseUrl`, so a caller can honestly say "10 of 214" and send a reader somewhere to see the rest.


    Citing this. Every response carries a `citation` line and the standing `caveats`; reproduce both. Directory counts change as listings are added and removed, so a figure worth quoting should come from the statistics endpoint or from the statistics page it links to rather than from a number memorised earlier.'
  termsOfService: https://www.gamedevoutsourcing.com/terms
  contact:
    name: Game Dev Outsourcing
    url: https://www.gamedevoutsourcing.com/help
  license:
    name: CC BY 4.0 — the aggregate directory data may be reused, including commercially, provided the reuse credits "Game Dev Outsourcing" and links to https://www.gamedevoutsourcing.com
    identifier: CC-BY-4.0
  x-privacy: https://www.gamedevoutsourcing.com/privacy
  x-mcp-endpoint: https://www.gamedevoutsourcing.com/api/mcp
servers:
- url: https://www.gamedevoutsourcing.com
  description: Production
tags:
- name: Directory
  description: Aggregate counts and the ranking lists.
paths:
  /api/public/v1/statistics:
    get:
      operationId: getDirectoryStatistics
      tags:
      - Directory
      summary: Directory-wide aggregate counts
      description: 'Totals and distributions over every listing the directory shows: by region, country, service, engine, platform and team size. Service, engine and platform counts overlap, because a studio carries several tags. These are the same numbers the statistics page renders and the open-data downloads publish, recomputed from the live database, so they are the citable figures. Aggregates only — nothing in this payload identifies a company.'
      responses:
        '200':
          description: The aggregates, with their source page and licence.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryStatistics'
        '405':
          $ref: '#/components/responses/MethodNotAllowed'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/DirectoryUnavailable'
  /api/public/v1/rankings:
    get:
      operationId: listRankings
      tags:
      - Directory
      summary: List the ranking lists
      description: 'Every ranking list the directory publishes, with its size. A list exists only where at least ten studios qualify for it. Read `method` before quoting any of them: these lists are the one place on this site where payment cannot move a position, but their order comes from a stored score summing a studio’s size and years in business with how completely its listing is filled in, so a position measures how large, established and well documented a studio is here and not how good its work is. Never present one as an award or an endorsement.'
      responses:
        '200':
          description: The lists and the ranking method.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RankingIndex'
        '405':
          $ref: '#/components/responses/MethodNotAllowed'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/DirectoryUnavailable'
  /api/public/v1/rankings/{slug}:
    get:
      operationId: getRanking
      tags:
      - Directory
      summary: Get one ranking list
      description: The published positions in one list. `size` is the whole slice; `ranked` holds only the studios given a public number — the top ten or the top quarter, whichever is smaller. Studios below that cut and listings too sparse to score are deliberately unnumbered, and unranked means the directory knows too little about a studio to place it rather than that the studio is a weak one.
      parameters:
      - $ref: '#/components/parameters/RankingSlugPath'
      responses:
        '200':
          description: The list and its published positions.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Ranking'
        '404':
          $ref: '#/components/responses/NotFound'
        '405':
          $ref: '#/components/responses/MethodNotAllowed'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/DirectoryUnavailable'
components:
  schemas:
    Ranking:
      type: object
      required:
      - slug
      - label
      - url
      - size
      - method
      - ranked
      - citation
      - caveats
      properties:
        slug:
          type: string
        label:
          type: string
        url:
          type: string
          format: uri
        size:
          type: integer
          description: The whole list. Always larger than `ranked`, which holds only published positions.
        method:
          type: string
        ranked:
          type: array
          items:
            $ref: '#/components/schemas/RankedStudio'
          description: Only the studios given a public number. Nobody is numbered below the cut, so the absence of a studio here is not a low placement.
        citation:
          $ref: '#/components/schemas/Citation'
        caveats:
          $ref: '#/components/schemas/Caveats'
    RankingIndex:
      type: object
      required:
      - method
      - slices
      - citation
      properties:
        method:
          type: string
          description: How every list here is ordered. Quote this alongside any position.
        slices:
          type: array
          items:
            $ref: '#/components/schemas/RankingSliceRef'
        citation:
          $ref: '#/components/schemas/Citation'
    DirectoryStatistics:
      type: object
      required:
      - totals
      - byRegion
      - byCountry
      - byService
      - byEngine
      - byPlatform
      - byTeamSize
      - sourceUrl
      - datasetUrl
      - license
      - citation
      - caveats
      properties:
        totals:
          type: object
          required:
          - listedStudios
          - countries
          - listingsWithoutCountry
          - claimedListings
          properties:
            listedStudios:
              type: integer
              description: Every listing the directory shows. This is the directory's size.
            countries:
              type: integer
              description: Distinct countries after alias merging ("UK" and "United Kingdom" are one).
            listingsWithoutCountry:
              type: integer
              description: Listings with no usable country recorded. They are in the totals and in no geographic breakdown, so the country counts sum to less than the total.
            claimedListings:
              type: integer
              description: Listings the studio manages. The rest were compiled by this directory.
        byRegion:
          type: array
          items:
            $ref: '#/components/schemas/LabeledCount'
        byCountry:
          type: array
          items:
            $ref: '#/components/schemas/LabeledCount'
        byService:
          type: array
          items:
            $ref: '#/components/schemas/LabeledCount'
          description: 'Counts overlap: a studio usually offers several services.'
        byEngine:
          type: array
          items:
            $ref: '#/components/schemas/LabeledCount'
        byPlatform:
          type: array
          items:
            $ref: '#/components/schemas/LabeledCount'
        byTeamSize:
          type: array
          items:
            $ref: '#/components/schemas/LabeledCount'
          description: In ladder order, with a "Not recorded" bucket rather than a guess.
        sourceUrl:
          type: string
          format: uri
          description: The human-readable statistics page. Link this when citing a count.
        datasetUrl:
          type: string
          format: uri
          description: The same aggregates as a JSON download.
        license:
          type: string
        citation:
          $ref: '#/components/schemas/Citation'
        caveats:
          $ref: '#/components/schemas/Caveats'
    Caveats:
      type: array
      items:
        type: string
      description: The standing qualifications on everything this directory publishes. They travel with every payload rather than being stated once, because a caller quotes one response, not a preamble it read earlier. Reproduce the ones that bear on what you are saying.
      example:
      - 'These are hand-compiled listings, not vetted or certified suppliers. Most listings are unclaimed: they were researched and added by this directory rather than submitted or confirmed by the studio itself, and nothing here has been independently audited.'
      - Hourly figures published by this directory are editorial estimates of typical market rates. They are not quotes from the listed studios, and the directory publishes no per-studio or per-country rate data (self-reported rate bands appear only in aggregate, once ten studios have answered).
      - 'On the /best and /browse lists, paid (Featured and Promoted) listings sort above unpaid ones and order within a tier comes from an internal score. Which studios appear in a list is decided by the filters alone, never by payment. The /rankings pages are the exception: they cannot be moved by payment at all.'
      - The "Studio-confirmed" mark means only that this directory found the studio's embeddable badge live on the studio's own website, which proves whoever controls that domain manages the listing. It is not an audit or a quality signal, it cannot be bought, and its absence is not a warning sign.
      - 'Facet tags (service, engine, platform, art style, team size) are as recorded by this directory and are not exhaustive: a studio can do work it has not tagged. Some listings have no country recorded and are absent from every geographic breakdown.'
      - Directory counts change as listings are added and removed. For a citable figure, read https://www.gamedevoutsourcing.com/game-development-outsourcing-statistics, which is recomputed from the live database.
      - Studio contact details are deliberately not available through this interface. Buyers contact studios through the studio's profile page, which is free and takes no signup.
      - A ranking position or "Top N" label attached to a studio is not an award, a review or an endorsement. Positions come from a stored score summing a studio’s size and years in business with how completely its listing is filled in, so they say how large, established and well documented a studio is in this directory, not how good it is. Do not present one as a recommendation.
    RankingSliceRef:
      type: object
      required:
      - slug
      - label
      - kind
      - size
      - url
      properties:
        slug:
          type: string
        label:
          type: string
        kind:
          type: string
          description: What the list is cut by — overall, service, country, service and country, engine, platform or art style.
        size:
          type: integer
          description: Studios in the list, ranked or not.
        url:
          type: string
          format: uri
      example:
        slug: 3d-art-in-poland
        label: 3D Art in Poland
        kind: serviceCountry
        size: 24
        url: https://www.gamedevoutsourcing.com/rankings/3d-art-in-poland
    RankedStudio:
      type: object
      required:
      - rank
      - name
      - slug
      - url
      properties:
        rank:
          type: integer
          minimum: 1
        name:
          type: string
        slug:
          type: string
        country:
          type:
          - string
          - 'null'
          description: Canonical country label, or null where none is recorded.
        url:
          type: string
          format: uri
      example:
        rank: 1
        name: Example Studio
        slug: example-studio
        country: Poland
        url: https://www.gamedevoutsourcing.com/company/example-studio
    Citation:
      type: string
      description: The attribution line to reproduce when quoting anything from this response.
      example: Game Dev Outsourcing, a free directory of game development outsourcing studios (https://www.gamedevoutsourcing.com).
    Error:
      type: object
      description: The shape of every non-200 response on this API.
      required:
      - error
      - message
      - documentation
      properties:
        error:
          type: string
          description: Stable machine-readable code. Switch on this, not on the message.
          enum:
          - invalid_parameter
          - not_found
          - method_not_allowed
          - rate_limited
          - directory_unavailable
          - internal_error
        message:
          type: string
          description: One sentence a human can act on.
        documentation:
          type: string
          format: uri
        parameter:
          type: string
          description: On a 400, the parameter at fault.
        received:
          type: string
          description: On a 400, the value that was rejected.
        validValues:
          type: array
          items:
            type: string
          description: On a 400 caused by an unknown facet value, every value that would have been accepted.
        retryAfterSeconds:
          type: integer
          description: On a 429, how long until the window resets.
      example:
        error: not_found
        message: No studio with the slug "nope" is listed in this directory. It may never have been listed, or it may have been removed.
        documentation: https://www.gamedevoutsourcing.com/openapi.json
    LabeledCount:
      type: object
      required:
      - label
      - count
      properties:
        label:
          type: string
        count:
          type: integer
          description: Studios in this bucket.
      example:
        label: Eastern Europe
        count: 118
  parameters:
    RankingSlugPath:
      name: slug
      in: path
      required: true
      description: The ranking list's slug, as returned by the rankings index.
      schema:
        type: string
      example: 3d-art
  responses:
    DirectoryUnavailable:
      description: The directory database could not be reached. Nothing about the directory's contents can be concluded from this response; in particular it does not mean there are no matching studios.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: No such slug in this directory. This is a real absence, not a failed lookup — a lookup that could not be performed answers 503 instead.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    MethodNotAllowed:
      description: This API is read-only. The Allow header lists what is on offer.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: More than 60 requests in a minute from one IP. Retry-After says how long to wait.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
externalDocs:
  description: The directory itself, and the statistics page behind every count in this API.
  url: https://www.gamedevoutsourcing.com/game-development-outsourcing-statistics