Back to top

Beeple Marketplace

If you are here it means you want to start writing a Marketplace extension.

Writing a marketplace application consists of multiple steps

  1. Write your extension definition. This is a JSON file giving your extension a name and related information.

  2. Install a server which will accept a callback for every time your application is installed on a Beeple customers site. This can be useful to track invoicing if you provide a paid application.

  3. Provide a web server which will accept webhooks from the Beeple system where you can interact with Beeple.

Writing your extension definition

An extension definition is a JSON file providing some details about your application.

Currently we don’t have a user interface where you as a 3rd-party developer can upload or manage your extensions. For the time being send your request to support@beeple.eu

This is an example of such JSON file

{
  "meta": {
    "reverse_dns": "eu.beeple.example",
    "name": "Example Name",
    "description": "A description of your application",
    "logo": "http://www.beeple.eu/image.png",
    "website": "http://www.beeple.eu"
  },
  "types": ["example"],
  "install-callback": "http://example.beeple.eu/install-callback",
  "configuration": [
    {
      "key": "somekey",
      "type": "string",
      "label": "Some config",
      "help": "An help text describing the config variable"
    }
  ]
}

In the meta section you describe some information about your application.

The key reverse_dns is a unique identifier for your application. It is in the format of a reverse DNS.

The key name is rather self-explanatory. This name will be displayed to users of Beeple looking for marketplace extensions

The key description is the description of the app. It is recommended to keep this clear and brief. A good description should be one or 2 sentences.

The logo field should be a URL pointing to an image of your app. The file should be a PNG file with dimensions 256x256 pixels. The beeple system will download this file at time of import of the extension. When your logo needs an update, an updated json file needs to be provided.

The types field is an array of specific types your application supports. An application can support zero or more types. Depending on the type or types Beeple will allow you more or less rights to interact with Beeple.

A list of supported types

  • communication-channel::sms if your app is responsible for sending SMS

  • payroll if your app is responsible for payrolling. See the payroll API’s documentation for more info. A payroll marketplace should add some info in its install callback about the payroll integration (endpoint and so on). Details are in the install callback response.

Other types will be added in the future

The install-callback field is a URL which should implement the API described in the next section. It will be called every time a Beeple customer installs the application.

The configuration section can be used to request configuration parameters for your application. The idea here is to request API keys and the like that your app needs.

Marketplace setup

Installation

The URL is a placeholder. You can fully specify this in your JSON description.

Installation
POST/install-callback

Example URI

POST /install-callback
Request
HideShow
Headers
Content-Type: application/json
Body
{
  "beeple_tenant_id": "ddde1555-9bb6-4180-91f4-db063f54c9c8",
  "endpoint": "beeple.example.org",
  "configuration": [
    {
      "key": "api_key",
      "value": "k2YxMNNYXbcZYPA6CtMEHjSz"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "beeple_tenant_id": {
      "type": "string",
      "description": "The ID of the tenant. A UUID which will not change."
    },
    "endpoint": {
      "type": "string",
      "description": "The endpoint host to which callbacks need to be sent"
    },
    "configuration": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "description": "The name of the configuration key"
          },
          "value": {
            "type": "string",
            "description": "The value of the configuration as entered by users who\n\ninstall the marketplace application."
          }
        }
      }
    }
  }
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "webhooks": [
    {
      "type": "sms",
      "url": "http://example.org/callback",
      "shared_key": "a random string"
    }
  ],
  "payroll": {
    "name": "Example Payroll",
    "contract_type": "interim",
    "endpoint": "https://example.org/beeple/payroll",
    "company_identification": "guid",
    "private_key": "another-guid",
    "allow_to_enter_payroll_identification": true
  },
  "custom_planning_field_groups": [
    {
      "name": [
        {
          "language": "en",
          "value": "translated text"
        }
      ],
      "fields": [
        {
          "name": [
            {
              "language": "en",
              "value": "translated text"
            }
          ],
          "description": [
            {
              "language": "en",
              "value": "translated text"
            }
          ],
          "level": "project",
          "public": true,
          "property_type": "numeric",
          "numeric_whole_number": true,
          "required": false,
          "use_as_filter": false,
          "dictionary_key": "EXAMPLE"
        }
      ]
    }
  ],
  "availability_types": [
    {
      "name": [
        {
          "language": "en",
          "value": "translated text"
        }
      ],
      "description": [
        {
          "language": "en",
          "value": "translated text"
        }
      ],
      "abbreviation": [
        {
          "language": "en",
          "value": "translated text"
        }
      ],
      "is_plannable": false,
      "allow_overlap_existing_enrolments": true,
      "planning_approval_required": true,
      "create_admin_notifications": true,
      "allow_entry_by_collaborator": true,
      "allow_remark": true,
      "color": "#ffaabb",
      "enter_per": "free",
      "show_on_work_schedule": true
    }
  ],
  "tenant_collaborator_settings": {
    "contact_person": {
      "request": "required",
      "show_at_application": false,
      "read_only": false
    },
    "bank_account": {
      "request": "required",
      "show_at_application": false,
      "read_only": false
    },
    "primary_address": {
      "request": "required",
      "show_at_application": false,
      "read_only": false
    },
    "profile_picture": {
      "request": "required",
      "show_at_application": false,
      "read_only": false
    },
    "nationality": {
      "request": "required",
      "show_at_application": false,
      "read_only": false
    },
    "national_registration_number": {
      "request": "required",
      "show_at_application": false,
      "read_only": false
    },
    "gender": {
      "request": "required",
      "show_at_application": false,
      "read_only": false
    },
    "birth_date": {
      "request": "required",
      "show_at_application": false,
      "read_only": false
    },
    "birth_place_and_country": {
      "request": "required",
      "show_at_application": false,
      "read_only": false
    },
    "mobile": {
      "request": "required",
      "show_at_application": false,
      "read_only": false
    },
    "secondary_phone_number": {
      "request": "required",
      "show_at_application": false,
      "read_only": false
    },
    "social_statute": {
      "request": "required",
      "show_at_application": false,
      "read_only": false
    },
    "email_auto_validation": false
  },
  "feedback_url": "https://feedback.example.org/one-time-code/"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "webhooks": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "sms"
            ],
            "description": "The type of webhook"
          },
          "url": {
            "type": "string",
            "description": "The URL of the endpoint"
          },
          "shared_key": {
            "type": "string",
            "description": "The (shared) key used to do authentication"
          }
        }
      }
    },
    "payroll": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "The name of the payroll integration. Recommended is the name of the marketplace"
        },
        "contract_type": {
          "type": "string",
          "description": "The contract type that this payroll supports"
        },
        "endpoint": {
          "type": "string",
          "description": "The URL used as endpoint for the payroll API's"
        },
        "company_identification": {
          "type": "string",
          "description": "The company identification."
        },
        "private_key": {
          "type": "string",
          "description": "The private key used for communication between 2 hosts"
        },
        "allow_to_enter_payroll_identification": {
          "type": "boolean",
          "description": "If admins are allowed to enter the payroll identification for a collaborator"
        }
      },
      "description": "Info for the payroll integration,\n\nonly needed for marketplace items of type payroll."
    },
    "custom_planning_field_groups": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "language": {
                  "type": "string",
                  "description": "The language code (2 letter ISO code)"
                },
                "value": {
                  "type": "string",
                  "description": "The translated text"
                }
              }
            },
            "description": "The name of the group in multiple langauges"
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "language": {
                        "type": "string",
                        "description": "The language code (2 letter ISO code)"
                      },
                      "value": {
                        "type": "string",
                        "description": "The translated text"
                      }
                    }
                  },
                  "description": "The name of the custom field in multiple languages"
                },
                "description": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "language": {
                        "type": "string",
                        "description": "The language code (2 letter ISO code)"
                      },
                      "value": {
                        "type": "string",
                        "description": "The translated text"
                      }
                    }
                  },
                  "description": "The description of the custom field in multiple languages"
                },
                "level": {
                  "type": "string",
                  "enum": [
                    "project",
                    "subproject",
                    "team"
                  ],
                  "description": "The level on which the property appears (defaults will be added to the levels above)"
                },
                "public": {
                  "type": "boolean",
                  "description": "If the planning field is visible to collea"
                },
                "property_type": {
                  "type": "string",
                  "enum": [
                    "numeric",
                    "freetext"
                  ],
                  "description": "The type of the property"
                },
                "numeric_whole_number": {
                  "type": "boolean",
                  "description": "Only applicable for numeric types, true if only whole numbers are allowed"
                },
                "required": {
                  "type": "boolean",
                  "description": "Is this a required field"
                },
                "use_as_filter": {
                  "type": "boolean",
                  "description": "Can the user filter on this field"
                },
                "dictionary_key": {
                  "type": "string",
                  "description": "The key name of the dictionary. All capps is highly recommended."
                }
              }
            },
            "description": "Fields in this group"
          }
        }
      },
      "description": "List of availability groups to be created"
    },
    "availability_types": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "language": {
                  "type": "string",
                  "description": "The language code (2 letter ISO code)"
                },
                "value": {
                  "type": "string",
                  "description": "The translated text"
                }
              }
            },
            "description": "The name of the availability type in multiple languages"
          },
          "description": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "language": {
                  "type": "string",
                  "description": "The language code (2 letter ISO code)"
                },
                "value": {
                  "type": "string",
                  "description": "The translated text"
                }
              }
            },
            "description": "The description of the availability type in multiple languages"
          },
          "abbreviation": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "language": {
                  "type": "string",
                  "description": "The language code (2 letter ISO code)"
                },
                "value": {
                  "type": "string",
                  "description": "The translated text"
                }
              }
            },
            "description": "The abbreviation of the availability type in multiple languages"
          },
          "is_plannable": {
            "type": "boolean",
            "description": "If the availability is marked as plannable"
          },
          "allow_overlap_existing_enrolments": {
            "type": "boolean",
            "description": "If the availability allows new entries to be entered even if there are already enrolments, note only applicable if is plannable is false"
          },
          "planning_approval_required": {
            "type": "boolean",
            "description": "If the availability requires approval by the admin"
          },
          "create_admin_notifications": {
            "type": "boolean",
            "description": "If when the user enters the availability admin notifications should be made"
          },
          "allow_entry_by_collaborator": {
            "type": "boolean",
            "description": "If the availability can be entered by the collaborator"
          },
          "allow_remark": {
            "type": "boolean",
            "description": "If the availability is marked as plannable"
          },
          "color": {
            "type": "string",
            "description": "If the availability is marked as plannable"
          },
          "enter_per": {
            "type": "string",
            "enum": [
              "free",
              "day",
              "day_part"
            ],
            "description": "How availabilities can be entered (free times, per whole day, or with day parts)"
          },
          "show_on_work_schedule": {
            "type": "boolean",
            "description": "If the availability is marked as plannable"
          }
        }
      },
      "description": "List of availability types to be created"
    },
    "tenant_collaborator_settings": {
      "type": "object",
      "properties": {
        "contact_person": {
          "type": "object",
          "properties": {
            "request": {
              "type": "string",
              "enum": [
                "required",
                "optional",
                "never"
              ],
              "description": "Whether the info should be requested, and if so if it is required"
            },
            "show_at_application": {
              "type": "boolean",
              "description": "Show the field during the application to the new collaborator"
            },
            "read_only": {
              "type": "boolean",
              "description": "Determine if the field should be readonly in beeple (eg fully managed by API)"
            }
          },
          "description": "Change the requirement settings for the Emergency Contact"
        },
        "bank_account": {
          "type": "object",
          "properties": {
            "request": {
              "type": "string",
              "enum": [
                "required",
                "optional",
                "never"
              ],
              "description": "Whether the info should be requested, and if so if it is required"
            },
            "show_at_application": {
              "type": "boolean",
              "description": "Show the field during the application to the new collaborator"
            },
            "read_only": {
              "type": "boolean",
              "description": "Determine if the field should be readonly in beeple (eg fully managed by API)"
            }
          },
          "description": "Change the requirmenent settings for the bank account"
        },
        "primary_address": {
          "type": "object",
          "properties": {
            "request": {
              "type": "string",
              "enum": [
                "required",
                "optional",
                "never"
              ],
              "description": "Whether the info should be requested, and if so if it is required"
            },
            "show_at_application": {
              "type": "boolean",
              "description": "Show the field during the application to the new collaborator"
            },
            "read_only": {
              "type": "boolean",
              "description": "Determine if the field should be readonly in beeple (eg fully managed by API)"
            }
          },
          "description": "Change the requirmenent settings for the address"
        },
        "profile_picture": {
          "type": "object",
          "properties": {
            "request": {
              "type": "string",
              "enum": [
                "required",
                "optional",
                "never"
              ],
              "description": "Whether the info should be requested, and if so if it is required"
            },
            "show_at_application": {
              "type": "boolean",
              "description": "Show the field during the application to the new collaborator"
            },
            "read_only": {
              "type": "boolean",
              "description": "Determine if the field should be readonly in beeple (eg fully managed by API)"
            }
          },
          "description": "Change the requirmenent settings for the profile picture"
        },
        "nationality": {
          "type": "object",
          "properties": {
            "request": {
              "type": "string",
              "enum": [
                "required",
                "optional",
                "never"
              ],
              "description": "Whether the info should be requested, and if so if it is required"
            },
            "show_at_application": {
              "type": "boolean",
              "description": "Show the field during the application to the new collaborator"
            },
            "read_only": {
              "type": "boolean",
              "description": "Determine if the field should be readonly in beeple (eg fully managed by API)"
            }
          },
          "description": "Change the requirmenent settings for the nationality"
        },
        "national_registration_number": {
          "type": "object",
          "properties": {
            "request": {
              "type": "string",
              "enum": [
                "required",
                "optional",
                "never"
              ],
              "description": "Whether the info should be requested, and if so if it is required"
            },
            "show_at_application": {
              "type": "boolean",
              "description": "Show the field during the application to the new collaborator"
            },
            "read_only": {
              "type": "boolean",
              "description": "Determine if the field should be readonly in beeple (eg fully managed by API)"
            }
          },
          "description": "Change the requirmenent settings for the national registration number"
        },
        "gender": {
          "type": "object",
          "properties": {
            "request": {
              "type": "string",
              "enum": [
                "required",
                "optional",
                "never"
              ],
              "description": "Whether the info should be requested, and if so if it is required"
            },
            "show_at_application": {
              "type": "boolean",
              "description": "Show the field during the application to the new collaborator"
            },
            "read_only": {
              "type": "boolean",
              "description": "Determine if the field should be readonly in beeple (eg fully managed by API)"
            }
          },
          "description": "Change the requirmenent settings for the gender"
        },
        "birth_date": {
          "type": "object",
          "properties": {
            "request": {
              "type": "string",
              "enum": [
                "required",
                "optional",
                "never"
              ],
              "description": "Whether the info should be requested, and if so if it is required"
            },
            "show_at_application": {
              "type": "boolean",
              "description": "Show the field during the application to the new collaborator"
            },
            "read_only": {
              "type": "boolean",
              "description": "Determine if the field should be readonly in beeple (eg fully managed by API)"
            }
          },
          "description": "Change the requirmenent settings for the birth date"
        },
        "birth_place_and_country": {
          "type": "object",
          "properties": {
            "request": {
              "type": "string",
              "enum": [
                "required",
                "optional",
                "never"
              ],
              "description": "Whether the info should be requested, and if so if it is required"
            },
            "show_at_application": {
              "type": "boolean",
              "description": "Show the field during the application to the new collaborator"
            },
            "read_only": {
              "type": "boolean",
              "description": "Determine if the field should be readonly in beeple (eg fully managed by API)"
            }
          },
          "description": "Change the requirmenent settings for the birth place and country"
        },
        "mobile": {
          "type": "object",
          "properties": {
            "request": {
              "type": "string",
              "enum": [
                "required",
                "optional",
                "never"
              ],
              "description": "Whether the info should be requested, and if so if it is required"
            },
            "show_at_application": {
              "type": "boolean",
              "description": "Show the field during the application to the new collaborator"
            },
            "read_only": {
              "type": "boolean",
              "description": "Determine if the field should be readonly in beeple (eg fully managed by API)"
            }
          },
          "description": "Change the requirmenent settings for the mobile"
        },
        "secondary_phone_number": {
          "type": "object",
          "properties": {
            "request": {
              "type": "string",
              "enum": [
                "required",
                "optional",
                "never"
              ],
              "description": "Whether the info should be requested, and if so if it is required"
            },
            "show_at_application": {
              "type": "boolean",
              "description": "Show the field during the application to the new collaborator"
            },
            "read_only": {
              "type": "boolean",
              "description": "Determine if the field should be readonly in beeple (eg fully managed by API)"
            }
          },
          "description": "Change the requirmenent settings for the phone number"
        },
        "social_statute": {
          "type": "object",
          "properties": {
            "request": {
              "type": "string",
              "enum": [
                "required",
                "optional",
                "never"
              ],
              "description": "Whether the info should be requested, and if so if it is required"
            },
            "show_at_application": {
              "type": "boolean",
              "description": "Show the field during the application to the new collaborator"
            },
            "read_only": {
              "type": "boolean",
              "description": "Determine if the field should be readonly in beeple (eg fully managed by API)"
            }
          },
          "description": "Change the requirmenent settings for the social statute"
        },
        "email_auto_validation": {
          "type": "boolean",
          "description": "Determines whether email changes by the admin are automatically validated"
        }
      },
      "description": "Allow settings for the tenant to be changed"
    },
    "feedback_url": {
      "type": "string",
      "description": "After the installation of all the payroll services, webhooks, specified availability types etc.. is complete a request will be done on this URL"
    }
  }
}

Installation feedback

The URL is a placeholder. You can fully specify this in your installaction callback response

Installation
POST/install-callback-response

Example URI

POST /install-callback-response
Request
HideShow
Headers
Content-Type: application/json
Body
{
  "payroll_id": "7777",
  "custom_planning_field_group_ids": [
    {
      "group_id": "133",
      "fields_ids": [
        "105"
      ]
    }
  ],
  "created_availability_types_ids": [
    "44"
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "payroll_id": {
      "type": "string",
      "description": "The Beeple ID of the created payroll if one specified"
    },
    "custom_planning_field_group_ids": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "group_id": {
            "type": "string",
            "description": "The ID of the group created"
          },
          "fields_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The IDs of the items created (in the order they were specified)"
          }
        }
      },
      "description": "List of Beeple ID's for all availability types (in the same order as specified in the creation)"
    },
    "created_availability_types_ids": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "List of Beeple ID's for all availability types (in the same order as specified in the creation)"
    }
  }
}
Response  200
HideShow
Headers
Content-Type: application/json

Generated by aglio on 14 Oct 2021