API Reference

Troop Marketplace: API Reference

With Troop Marketplace, you can import/update every piece of information in your map layers by using the public Graphql API that runs on Apollo Server. This API reference provides comprehensive details for integrating with the GraphQL project implemented using Apollo Server.
If you want to import your data using this method and use the Troop API, contact us at: [email protected].
Please note that this API reference assumes prior knowledge of GraphQL concepts. If you're new to GraphQL, we recommend familiarizing yourself with its basics before using this documentation. Should you encounter difficulties or have questions, the GraphQL and Apollo Server communities offer ample resources and support.

Before you start

  1. 1.
    Request access to the Troop API by contacting us at: [email protected].
  2. 2.
    Get the app ID and API Key.
Before you manipulate your app, you should ask the owner of the app for the following information:
Name
Description
Example
appId
Your app ID, a 36-character UUID string.
230d1cef-3223-4d38-a751-4326e2a9c015
apiKey
The API key for your app.
c4vedznaru8t2ygeut8235fbw018rh
  1. 3.
    Read the model reference.
It's important that you understand the model of the Troop Marketplace before manipulating data. Reading it will take you less than 5 minutes.

Authorization

All the endpoints from the Troop Marketplace schema require API Key authentication. Please make sure you query the graph using the following fields in your request headers:
Name
Value
Example
Authorization
Api-Key {{YOUR_API_KEY}}
Api-Key c4vedznaru8t2ygeut8235fbw018rh

Quick start

  1. 1.
    Create features.
A feature is each one of the entities represented in your map layer, that will contain data. In order to manipulate features, you can use the following Graphql operations:
  • createOneFeature
  • createManyFeatures
  • updateOneFeature
  • deleteOneFeature
  • deleteManyFeatures

Examples

Example mutation to create a feature:
mutation CreateOneFeature($input: CreateOneFeatureInput!) {
createOneFeature(input: $input) {
id
created
updated
title
bbox
type
country
city
coordinates
appId
}
}
Apps of subtype PLACE_DATA_GEOGRAPHIC_AREA:
Example mutation variables:
{
"input": {
"appId": "{{YOUR_APP_ID}}",
"bbox": [],
"title": "Camerooon",
"country": "CM"
}
}
Example response:
{
"data": {
"createOneFeature": {
"id": "{{FEATURE_ID}}",
"created": 1686907384880,
"updated": 1686907384880,
"title": "Camerooon",
"bbox": [],
"type": null,
"country": "CM",
"city": null,
"coordinates": null,
"appId": "{{YOUR_APP_ID}}"
}
}
}
Apps of subtype PLACE_DATA_GEOGRAPHIC_LOCATION:
Example mutation variables:
{
"input": {
"appId": "{{YOUR_APP_ID}}",
"bbox": [],
"title": "Office at Cameroon",
"country": "CM",
"type": "Point",
"coordinates": [12.3547, 7.3697]
}
}
Example response:
{
"data": {
"createOneFeature": {
"id": "{{FEATURE_ID}}",
"created": 1686907486046,
"updated": 1686907486046,
"title": "Office at Cameroon",
"bbox": [],
"type": "Point",
"country": "CM",
"city": null,
"coordinates": [
12.3547,
7.3697
],
"appId": "{{YOUR_APP_ID}}"
}
}
}
  1. 2.
    Create the feature properties.
A feature property is every piece of data you specify for your feature. In order to manipulate features, you can use the following Graphql operations:
  • createOneFeatureProperty
  • createManyFeatureProperties
  • updateOneFeatureProperty
  • deleteOneFeatureProperty
  • deleteManyFeatureProperties
You can customize the style of the geographic entities in the map by creating feature properties with specific names. You can see the full list of reserved feature properties in the model reference.

Examples

Example mutation to create many feature properties for your feature:
mutation CreateManyFeatureProperties($input: CreateManyFeaturePropertiesInput!) {
createManyFeatureProperties(input: $input) {
count
}
}
Apps of subtype PLACE_DATA_GEOGRAPHIC_AREA:
Example mutation variables:
{
"input": {
"featureId": "{{YOUR_FEATURE_ID}}",
"featureProperties": [
{
"value": "21",
"name": "majority_age",
"dataType": "INT"
},
{
"value": "#FF0060",
"name": "fill_color",
"dataType": "STRING"
},
{
"value": "21 years old",
"name": "legend_title",
"dataType": "STRING"
}
]
}
}
Example response:
{
"data": {
"createManyFeatureProperties": {
"count": 3
}
}
}
Apps of subtype PLACE_DATA_GEOGRAPHIC_LOCATION:
Example mutation variables:
{
"input": {
"featureId": "9c029888-6364-441a-8147-92273766fd75",
"featureProperties": [
{
"value": "EcoHub Business Center",
"name": "display_name",
"dataType": "STRING"
},
{
"value": "[email protected]",
"name": "email_address",
"dataType": "STRING"
},
{
"value": "#F39C12",
"name": "fill_collor",
"dataType": "STRING"
},
{
"value": "8",
"name": "circle_radius",
"dataType": "INT"
},
{
"value": "Medium capacity",
"name": "legend_title",
"dataType": "STRING"
},
{
"value": "A medium capacity space is of moderate size and can accommodate a moderate number of people. Examples of medium capacity spaces include medium-sized conference rooms, mid-sized restaurants, or art studios.",
"name": "legend_description",
"dataType": "STRING"
}
]
}
}
Example response:
{
"data": {
"createManyFeatureProperties": {
"count": 5
}
}
}
  1. 3.
    Update the map style.
Once you're done importing all the features and feature properties, you need to manually update the style of the map. Your changes won't be visible on the map until you execute this operation. To update the style of the map, use the following operation:
  • updateTilesetSource
IMPORTANT: this operation is required only when you're using the API. However, when you're importing data from a Google Sheet, these updates are triggered automatically and you don't need to execute this operation.
You won't be able to execute this operation until the previous update has finished processing.

Examples

Example mutation to update the map layers:
mutation UpdateTilesetSource($appId: ID!) {
updateTilesetSource(appId: $appId) {
status
message
}
}
Example variables:
{
"appId": "{{YOUR_APP_ID}}"
}
Example response:
{
"data": {
"updateTilesetSource": {
"status": "SCHEDULED",
"message": "Tileset source updated successfully"
}
}
}

Graphql schema

schema {
mutation: Mutation
}
"A stringified JSON object."
scalar JSON
"A 13-character JavaScript timestamp."
scalar Timestamp
type Query {
"""Fetches an app by ID."""
app(id: ID!): App!
"""Fetches features by app ID."""
appFeatures(appId: ID!): [AppFeature!]!
"""Fetches feature properties by feature ID."""
featureProperties(featureId: ID!): [AppFeatureProperty!]!
"""Fetches cities."""
publicMarketplaceCities(country: String, region: String): [PublicSpatialCitySearchResponse]!
"""Fetches regions."""
publicMarketplaceRegions(country: String!): [PublicSpatialRegionSearchResponse]!
"""Fetches countries."""
publicMarketplaceCountries(continent: String!): [PublicSpatialCountrySearchResponse]!
}
extend type Mutation {
"""Updates tileset source on Mapbox."""
updateTilesetSource(appId: ID!): AsyncActionResponse!
"""Deletes tileset source from Mapbox."""
deleteTilesetSource(appId: ID!): AsyncActionResponse!
"""
Imports features and feature properties from a Google Sheet, and then updates tileset source on Mapbox.
"""
setXGoogleSheetCron(appId: ID!): AsyncActionResponse!
"""Creates one feature."""
createOneFeature(input: CreateOneFeatureInput!): AppFeature!
"""Creates many features under the same app."""
createManyFeatures(input: CreateManyAppFeaturesInput!): CreateManyAppFeaturesResponse!
"""Deletes one feature."""
deleteOneFeature(input: DeleteOneFeatureInput!): AppFeature!
"""Updates one feature."""
updateOneFeature(input: UpdateOneFeatureInput!): AppFeature!
"""Deletes many features."""
deleteManyFeatures(input: DeleteManyFeaturesInput!): DeleteManyFeaturesResponse!
"""Creates one feature property."""
createOneFeatureProperty(input: CreateOneFeaturePropertyInput!): AppFeatureProperty!
"""Deletes many feature properties."""
deleteManyFeatureProperties(input: DeleteManyFeaturePropertiesInput!): DeleteManyFeaturePropertiesResponse!
"""Creates many feature properties."""
createManyFeatureProperties(input: CreateManyFeaturePropertiesInput!): CreateManyFeaturePropertiesResponse!
"""Deletes one feature property."""
deleteOneFeatureProperty(input: DeleteOneFeaturePropertyInput!): AppFeatureProperty!
"""Updates one feature property."""
updateOneFeatureProperty(input: UpdateOneFeaturePropertyInput!): AppFeatureProperty!
}
type BannedPlace {
code: String!
title: String!
}
input PermissionInput {
"The permission category."
category: PermissionCategoryInput!
"The permission value."
value: String!
}
input CreateManyAppFeaturesInput {
"The app ID."
appId: ID!
"The list of feature inputs."
features: [CreateManyAppFeatureResourceInput!]!
}
input CreateManyAppFeatureResourceInput {
"The title of the feature."
title: String!
"The bounding box of the feature."
bbox: [Float!]!
"The type of the feature. Required for apps of subtype PLACE_DATA_GEOGRAPHIC_LOCATION."
type: FeatureGeoType
"The country ISO code of the feature."
country: String
region: String
"The city ISO code of the feature. Currently unsupported."
city: String
"The coordinates of the feature. Required for apps of subtype PLACE_DATA_GEOGRAPHIC_LOCATION."
coordinates: JSON
}
type CreateManyAppFeaturesResponse {
"The number of features created."
count: Int!
}
type Permission {
"The permission ID."
id: ID!
"The installation ID."
installationId: ID!
"The permission category."
category: PermissionCategory!
"The permission value."
value: String!
"The creation date."
created: Timestamp!
"The last update date."
updated: Timestamp!
}
input CreateOneFeatureInput {
"The app ID."
appId: ID!
"The title of the feature."
title: String!
"The bounding box of the feature."
bbox: [Float!]!
"The type of the feature. Required for apps of subtype PLACE_DATA_GEOGRAPHIC_LOCATION."
type: FeatureGeoType
"The country ISO code of the feature."
country: String
region: String
"The city ISO code of the feature. Currently unsupported."
city: String
"The coordinates of the feature. Required for apps of subtype PLACE_DATA_GEOGRAPHIC_LOCATION."
coordinates: JSON
}
input UpdateOneFeatureInput {
"The feature ID."
id: ID!
"The title of the feature."
title: String
"The bounding box of the feature."
bbox: [Float!]
"The type of the feature. Required for apps of subtype PLACE_DATA_GEOGRAPHIC_LOCATION."
type: FeatureGeoType
"The country ISO code of the feature."
country: String
region: String
"The city ISO code of the feature. Currently unsupported."
city: String
"The coordinates of the feature. Required for apps of subtype PLACE_DATA_GEOGRAPHIC_LOCATION."
coordinates: JSON
}
input UpdateOneFeaturePropertyInput {
"The feature property ID."
id: ID!
"The name of the feature property."
name: String
"The value of the feature property."
value: String
"The data type of the feature property."
dataType: DataType
}
input DeleteOneFeatureInput {
"The feature ID."
id: ID!
}
input DeleteOneFeaturePropertyInput {
"The feature property ID."
id: ID!
}
input CreateOneFeaturePropertyInput {
"The app ID."
appId: String!
"The feature ID."
featureId: String!
"The name of the feature property."
name: String!
"The value of the feature property."
value: String!
"The data type of the feature property."
dataType: DataType!
}
input CreateManyFeaturePropertiesInput {
"The feature ID."
featureId: ID!
"The name of the feature properties."
featureProperties: [CreateManyFeaturePropertiesResourceInput!]!
}
input CreateManyFeaturePropertiesResourceInput {
"The name of the feature property."
name: String!
"The value of the feature property."
value: String!
"The data type of the feature property."
dataType: DataType!
}
input TransfersPayloadOrigin {
iataCode: String
}
input TransfersPayloadDestination {
address: TransfersPayloadAddress
}
input TransfersPayloadAddress {
addressSearchPhrase: String
countryCode: String
}
type CreateManyFeaturePropertiesResponse {
"The number of created feature properties."
count: Int!
}
input DeleteManyFeaturesInput {
"The app ID."
appId: ID!
}
input DeleteManyFeaturePropertiesInput {
"The app ID."
appId: ID!
}
type DeleteManyFeaturesResponse {
"The number of deleted features."
count: Int!
}
type DeleteManyFeaturePropertiesResponse {
"The number of deleted feature properties."
count: Int!
}
type App {
"The app ID."
id: ID!
"The app name."
appName: String!
"The app description."
description: String!
"The thumbnail media ID."
thumbnailUrl: String
"Returns true if the application is Troop verified."
isVerified: Boolean!
"The creation date."
created: Timestamp!
"The date an app was last accessed."
lastAccessed: Timestamp
"The expiration date of the app."
expiryDate: Timestamp!
"The last update date."
updated: Timestamp!
"The app owner ID."
userId: String!
"The organization ID of the owner."
organizationId: String!
"The app status."
status: AppStatus!
"The app type."
type: AppType!
"The app subtype."
subType: AppSubType!
"The app visibility."
visibility: AppVisibility!
"The import status."
importStatus: ImportStatus
"Returns the number of time the app has been installed."
installationsCount: Int
"Returns true if the application is Troop Featured."
isFeatured: Boolean!
"The app IntegrationType"
integrationType: IntegrationType!
"The support email"
supportEmail: String
"The Last Updated Date"
lastUpdatedDate: Timestamp
"The amount of features linked to this app"
nFeatures: Int
}
type ImportStatus {
"The import status ID."
id: ID!
"The app ID."
appId: ID!
"The execution ID."
executionId: String!
"The status."
status: ImportStatusStatus!
"The name of the current stage."
current_stage: ImportStatusStage!
"The events related to the import operation."
events: JSON
"The creation date."
created: Timestamp!
"The last update date."
updated: Timestamp!
}
type AppFeature {
"The feature ID."
id: ID!
"The creation date."
created: Timestamp!
"The last update date."
updated: Timestamp!
"The title of the feature."
title: String!
"The bounding box of the feature."
bbox: [Float]
"The type of the feature. Required for apps of subtype PLACE_DATA_GEOGRAPHIC_LOCATION."
type: FeatureGeoType
"The country ISO code of the feature."
country: String
"The region ISO code of the feature."
region: String
"The city ISO code of the feature. Currently unsupported."
city: String
"The coordinates of the feature. Required for apps of subtype PLACE_DATA_GEOGRAPHIC_LOCATION."
coordinates: JSON
"The app ID."
appId: String!
}
type AppFeatureProperty {
"The feature property ID."
id: ID!
"The name of the feature property."
name: String!
"The value of the feature property."
value: String!
"The data type of the property"
dataType: DataType!
"The app ID."
appId: String!
"The feature ID."
featureId: String!
}
enum ImportStatusStatus {
PROCESSING
COMPLETED
CANCELLED
FAILED
}
enum ImportStatusStage {
READ_GOOGLE_SHEET
IMPORT_DATABASE
IMPORT_MAPBOX
PROCESS_TILESET
}
enum AppStatus {
DRAFT
READY
ARCHIVED
DISABLED
}
enum AppVisibility {
PUBLIC
PRIVATE
}
enum PermissionCategory {
OWNER
ORGANIZATION
USER
USER_ROLE
}
enum PermissionCategoryInput {
ORGANIZATION
USER
USER_ROLE
}
enum AppType {
PLACE_DATA
LOCAL_TRANSPORT
ORGANIZATION_DATA
}
enum AppSubType {
PLACE_DATA_GEOGRAPHIC_LOCATION
PLACE_DATA_GEOGRAPHIC_AREA
PLACE_DATA_EVENTS
LOCAL_TRANSPORT_RENTALS
ORGANIZATION_DATA_BANNED_PLACES
ORGANIZATION_DATA_OFFICE_LOCATIONS
ORGANIZATION_DATA_PLACE_CAPS
ORGANIZATION_DATA_CORPORATE_RATES
}
enum AsyncActionResponseStatus {
SCHEDULED
PENDING
SUCCESSFUL
FAILED
CANCELLED
}
enum DataType {
STRING
INT
JSON
DECIMAL
BOOLEAN
}
enum FeatureGeoType {
Point
MultiPoint
Polygon
MultiPolygon
LineString
MultiLineString
}
enum IntegrationType {
API_FETCH
API_IMPORT
GOOGLE_SHEET
}
type AsyncActionResponse {
"The response status."
status: AsyncActionResponseStatus!
"The response message."
message: String
}
type PublicSpatialCitySearchResponse {
"The city code."
code: String!
"The city name."
name: String
"The continent code."
continent_code: String
"The country code."
country_code: String
"The region code."
region_code: String
}
type PublicSpatialCountrySearchResponse {
"The country code."
code: String!
"The country name."
name: String
"The country code."
continent_code: String
}
type PublicSpatialRegionSearchResponse {
"The region code."
code: String!
"The region name."
name: String
"The country code."
continent_code: String
"The country code."
country_code: String
}
type TransfersDataResponseAddress {
bookerEnteredAddress: String
resolvedAddress: String
fullResolvedAddress: FullResolvedAddress
latitude: Float
longitude: Float
hub: Boolean
iataCode: String
}
type FullResolvedAddress {
streetName: String
streetNumber: String
city: String
postalCode: String
region: String
countryCode: String
establishment: String
}
type TravelAddon {
id: String
type: String
price: Float
commission: Float
maxAllowed: Int
}
type TransfersDataQuote {
id: String
vehicleCategory: String
vehicleImageUrl: String
passengerCapacity: Int
luggageCapacity: Int
price: Float
commission: Float
currencyCode: String
combinedBabyAndBoosterSeatsCapacity: Int
expires: String
availableTravelAddons: [TravelAddon]
includedWaitingTimeInMinutes: Int
freeCancellationUntil: String
pricePerPassenger: Boolean
}
type TransfersDataResponseQuoteCategory {
outbound: [TransfersDataQuote]
inbound: [TransfersDataQuote]
}
type TicketData {
USD: String
ItemID: String
Price: Float
PriceComments: String
Section: String
ServiceFee: Float
}