Matt Spinks
Matt Spinks

Reputation: 6698

How to create a new mapbox style programmatically via the mapbox api?

I am attempting to create a new mapbox style in my mapbox account programmatically via the api. However, I am finding the documentation for this to be lacking. The mapbox docs for creating a style via the api are here:

https://docs.mapbox.com/api/maps/#create-a-style

From a technical perspective, it seems simple enough. However, I am finding the practical implementation to be more complicated. The example they give (which I am using as a starting point) uses this structure:

{
  "version": 8,
  "name": "My Awesome Style",
  "metadata": { },
  "sources": {
    "myvectorsource": {
      "url": "mapbox://{tileset_id}",
      "type": "vector"
    },
    "myrastersource": {
      "url": "mapbox://{tileset_id}",
      "type": "raster"
    }
  },
  "glyphs": "mapbox://fonts/{username}/{fontstack}/{range}.pbf",
  "layers": [ ]
}

Simple enough. But this does not correlate very well to what I have been doing in the mapbox studio editor to create styles. In mapbox studio I start with a template like this: mapbox select a style template

I start with the "Basic" template, and then I proceed to add one of my custom layers in the editor: add my custom layer in the mapbox studio editor

That is essentially what I am trying to achieve programmatically via the mapbox api. However, I am stuck on 2 points, and these are my questions:

  1. The api endpoint for "create style" does not have an option for a "template". Instead, it allows for "sources" and "layers". How does the "basic" template correlate to sources and layers? In other words, what sources and layers do I need to add programmatically in order to achieve the result of the "basic template"?
  2. How do I add my custom layer to this "create style" request? I see that layers is an array. But an array of what? Urls? Ids? Something else? For reference, I desire to attach the following custom layer to my new style: custom layer to be added

Essentially, I would like to know what my payload needs to look like in order to create a new style using the basic template and one additional custom layer. So far I have tried this:

{
    "version": 8,
    "name": "test style via api",
    "metadata": null,
    "sources": {
        "myrastersource": {
            "url": "mapbox://styles/mapbox/streets-v11",
            "type": "raster"
        }
    },
    "glyphs": null,
    "layers": []
}

After which I receive the error "Source url must be a valid Mapbox tileset url".

And I have tried this:

{
    "version": 8,
    "name": "test style via api",
    "metadata": null,
    "sources": {
        "myrastersource": {
            "url": "mapbox://styles/mapbox/streets-v11",
            "type": "raster"
        }
    },
    "glyphs": null,
    "layers": ["kenazthomas.c8ieto90"]
}

After which I receive the error "layers[0]: either 'type' or 'ref' is required"

What should my payload look like?

Upvotes: 1

Views: 1063

Answers (1)

Rafael Almeida
Rafael Almeida

Reputation: 10732

The documentation of Mapbox's Maps API (of which the endpoint you're trying to call is a part of) mentions this under the top-level Styles header:

You will need to be familiar with the Mapbox Style Specification to use the Styles API. The Mapbox Style Specification defines the structure of map styles and is the open standard that helps Studio communicate with APIs and produce maps that are compatible with Mapbox libraries.

The relevant section of the Style object documentation is the Layers page, which contains details on the object field and its details, as well as an example:

"layers": [
  {
    "id": "water",
    "source": "mapbox-streets",
    "source-layer": "water",
    "type": "fill",
    "paint": {
      "fill-color": "#00ffff"
    }
  }
]

You will need to reference your custom uploaded layer in the source and source-layer fields, so you should probably look at the Sources object doc as well. Assuming your custom layer is a vector layer, you'll probably reference it with mapbox://<Tileset ID> in the Layer object.

Upvotes: 1

Related Questions