Chapters
Read help articles, documentation, and other information about setting up and using Venjue in your business
Choose an article from the menu
Highlighted articles
Embed the widget on your website
Easily embed the Venjue contact form widget on your website, as well as get in-depth explanations and examples on how to connect analytics and customize the widget to suit more advanced needs
Connect Venjue to your bookkeeping system
Follow our step-by-step guide to integrate Venjue with bookkeeping systems like Billy, e-conomic, Dinero, Dynamics 365 and more, and get a better understanding of how the integration works
Using seating and floor plans
Learn how to setup a floorplan for your venues, how to use it on a booking, and how seating, allergens and other guest notes work
Easily embed the Venjue contact form widget on your website, as well as get in-depth explanations and examples on how to connect analytics and customize the widget to suit more advanced needs
The Venjue Widget is a contact form embedded on a website, that handles booking inquiries and channels them into Venjue.
The widget can be added with a few lines of code. For added convenience we created a Wordpress plugin, that handles all the technicalities.
You can see a demo of the widget to see how it works.
To add the widget to any website, or to have the full flexibility of the widget's customization options, we recommend using the manual installation option.
Add the following script to the website's <head> tag, to have the widget available on the site.
<script src="https://venjue.com/widget/script.js"></script>
:::warning[Caution!] Use the Venjue domain as provided. Hosting the script yourself will hinder future updates to the widget's functionality on the embedded site, which might break functionality. :::
Add the following html before the closing </body> tag, and customize the setup to suit your needs by adding data-attributes to the container.
<div id="venjue-widget-container"
data-businessid="%%12345678%%(Provide ID of Venjue business)"
data-langcode="%%da_DK%%(Set desired language)"
data-accentcolor="%%#8e8df2%%(Set desired theme color)"
></div>
Consult the developer console in your browser for errors and logs from the widget.
Customization options (data-attributes)
Note: All data-attributes should be prefaced by 'data-' when added to the container, e.g.
data-businessid="42410047".
Attribute Supported values Note businessid String, the unique ID of the Venjue business's VAT (CVR no). langcode String, ' da_DK', 'en_DK' or another locale.Unsupported locales will fallback to en_DK.accentcolor String, a HEX color code, e.g. ' #8e8df2'.Include the hash (#) character. hidebutton Boolean, either trueorfalse.If set to true, the button that triggers the widget will be hidden and thus the functionality will be limited, and you should instead trigger the widget's opening programmatically using the appropriate method.hidebackdrop Boolean, either trueorfalse.googletagmanagerid String, e.g. ' GTM-xxxxxxxx'.The widget automatically detects an active Google Analytics setup, but in case a specific ID is needed, or the auto detection did not work, a Google Tag Manager ID can be specified.
Other options, like which steps to include in the inquiry flow, which products and venues to show, availability options and custom form fields are configured in Venjue.
The Wordpress plugin automatically performs the same actions as the manual installation and provides a settings page to manage the customization options.
To get started, search the Wordpress plugin store for "Venjue Widget", click »Install« and »Activate« to add the widget to your Wordpress site.
You can also download the Wordpress plugin and upload it to your Wordpress installation manually.
When the plugin is installed and activated, there will be a submenu under your Wordpress settings, where you can configure the widget. See below screenshot.

The widget hooks into an active Google Analytics integration and emits events for certain interactions. Measure visitor's interactions with the widget by setting up targets on these events in Google Analytics.
All activity will automatically be tracked if you use Google Tag Manager by gtag (gtag.js) or analytics.js (ga) for Google Analytics.
If the widget does not automatically detect a Google Analytics integration, or if several exist and a specific needs to be used, you can set the data-googletagmanagerid attribute instead.
:::[Inspect the Developer Console] If the widget has succesfully hooked into your Google Analytics setup, you will see messages logged in the developer console mentioning the event was emitted properly to the GTM Data Layer. :::
| Event | Action |
|---|---|
| venjueWidgetReady | Fired when the widget is initialized |
| venjueWidgetShown | Fired when the widget's contact form is shown to the user |
| venjueWidgetHidden | Fired when the widget's contact form is hidden from the user |
| venjueWidgetSubmitted | Fired when the widget inquiry is submitted by the user |
The Widget API provides methods to interact with the widget and events to tie other actions to the widget.
| Method | Action |
|---|---|
venjueWidget.show() |
Shows the widget's contact form for inquiries |
venjueWidget.hide() |
Hides the widget's contact form for inquiries |
| Event | Action |
|---|---|
| venjueWidgetReady | Fired when the widget is initialized |
| venjueWidgetShown | Fired when the widget's contact form is shown to the user |
| venjueWidgetHidden | Fired when the widget's contact form is hidden from the user |
| venjueWidgetSubmitted | Fired when the widget inquiry is submitted by the user |
The following is a code example to open the widget whenever clicking on a link, button or otherwise with the class of 'openVenjueWidget' on the element:
document.addEventListener("venjueWidgetReady", function() {
document.querySelector(".openVenjueWidget").addEventListener("click", function(event) {
event.preventDefault();
venjueWidget.show();
});
});
Follow our step-by-step guide to integrate Venjue with bookkeeping systems like Billy, e-conomic, Dinero, Dynamics 365 and more, and get a better understanding of how the integration works
Venjue can connect to your bookkeeping and invoicing system, so that financial transactions and invoicing automatically gets done.
On Venjue, you will be able to use debtors for bookings, keep track of payments and their invoice draft counterparts, customer payments will automatically appear on your journal vouchers on the debtor's account, and once you're ready to send the invoice, a single button press will transfer the booking for final invoicing and bookkeeping.
We support several integrations for bookkeeping, including:
- Visma e-conomic
- Billy by Shine (previously "Billy's Billing" and "Billy by Ageras")
- Dinero
- Microsoft Dynamics 365
To begin connecting Venjue with your bookkeeping system, please follow the below steps:
Login to Venjue and go to Settings → Integrations → Bookkeeping and click on »Connect«.
Select your bookkeeping system from the list.
Note: selections available in below screenshot can change as we add more systems.

Grant permission for Venjue to communicate with your bookkeeping system.
:::[Heads up!] In this example we're connecting with e-conomic, so the page you see might be a bit different. For some integrations you wil be presented by semi-manual instructions to follow to grant access. :::

Once done, you will be returned to Venjue to complete the setup.
After you return from granting access, you will be asked to complete the integration by configuring how Venjue should interact with your bookkeeping system.
The steps needed are presented to you and differs from integration to integration.
Select the different product categories Venjue should populate on invoice drafts, and other settings for this specific bookkeeping system.
:::warning[Caution] If you do not properly configure the integration, Venjue will not be able to communicate with your bookkeeping system. :::
Ensure that you:

When a booking gets confirmed by the customer, Venjue will automatically create a debtor (or re-use an existing one) with the customer's data.
When managing a booking on Venjue, you can prefill the debtor to use.
When a booking gets confirmed by the customer, Venjue will create a journal entry with the paid amount tied to the debtor account for the customer.
If there is a fee tied to the transaction, it will also be created along with an attached fee receipt.

When desired, you can click a single button and Venjue will create a new draft invoice in your bookkeeping system ready for approval.
The draft invoice will be tied to the debtor, have the customer's information, the invoice lines from the booking, a total price deducted the potential prepayment and Venjue's booking order confirmation attached.
Below is a preview of the generated invoice PDF from e-conomic.

Learn how to setup a floorplan for your venues, how to use it on a booking, and how seating, allergens and other guest notes work
The floorplan and seating tool in Venjue allows for easy creation of standardized floorplans and table arrangements.
A floorplan can be created with rooms, text, pictograms, tables and more for each venue.
From a booking, the general setup can be re-used and altered to fit the specific event. Table formations per venue allow for easy prefilling on a booking.
Allow your customer to view their floorplan, move tables, seat guests and more, or leave it to you and your staff. A customer can add to the guestlist, and even inform about allergens, guest notes and more.
To begin using the floorplan tool, you should start by creating a venue-specific floorplan, by heading to Venues in the navigation bar, then click »Edit floorplan«.
In the venue-specific floorplan, you can design the room, add pictograms like fire escapes and restrooms, add text and more. Once the basic layout has been made you can start adding tables.
Click on »Add element« to design the venue's floorplan.

If you have an often used arrangement of tables, you can add those, scale their dimensions, choose how chairs are positioned, give them a name and define a max amount of people to be seated on each table.
Alternatively, you can skip adding tables, and add them when editing the floorplan on a booking, if they're booking specific and no standard layout is needed.

When editing the floorplan for a booking, Venjue will use the venue's floorplan as a starting point and let you add, remove or edit tables, or use a table formation.
The rooms, pictograms, text and more that is tied to the venue will naturally not be editable from the booking.
To create a reuseable table formation, you can click »Create new« per the screenshot. All tables will be added to a new formation, and you can hover the newly created formation to rename or delete it.
To only add certain tables to the formation, click and drag to select those, before creating a new formation.
You can use multiple formations at the same time, add a formation multiple times, or clear all present tables from »Settings«.

If you click on »Settings«, you can choose if the floorplan tool should be available to the customer when they view their booking.
If enabled, you can also enable or disable whether the customer should be able to move tables and or seat guests from the guestlist.
Enabled options are inherited from the floorplan setup for the venue.

When editing the floorplan from a booking, you can select a table to add guests to. When added, the guest will also appear on the guestlist, where allergens and notes can be added to the guest. From the guestlist, you can also add guests and the guest can then be seated on a table directly.
Click and drag to reorder guest positions for the table.
Clicking on a chair configuration option will shift the seats to reflect the new positions, and clicking on the same configuration once more will change the side of the table they're seated on.
:::[Did you know] When a guest has an allergen, that matches an allergen present in a dish, it will be shown on exported documents like the BEO runsheet. :::

For you and your customer's convenience, it is possible to import a guestlist.
Any CSV encoded file is importable, like a spreadsheet or for instance a Facebook™ event's list of attendees.
Technical documentation on how to interact with the Venjue API, its endpoints and authentication method.
The Venjue API is a JSON-based RESTful API available to users directly1, and allows for advanced interactions with Venjue while off-platform.
We have a quick and easy way of generating authorization tokens for private integrations, as well as an OAuth-like flow available for official public integrations.
The API intentionally exposes only the most central data. If you need additional endpoints or expanded data from existing endpoints, we welcome your feedback. This is an initial release, and input from partners and customers helps guide future development and improvements.
The first step in interacting with the Venjue API is to create an access_token that allows outside services to interact with Venjue on your account's behalf.
If you're a user of Venjue, and would like to connect your other systems to Venjue, please begin the process by going there and following their integration setup.
:::warning[Third party developer] If you're a third party developer looking to create a publicly accessible and official integration, please refer to creating an official third party integration section. Third parties must use this method for the integration to be featured on Venjue. :::
Users of Venjue can quickly authenticate themselves, and get started with no fuss, so that they can connect custom solutions to Venjue.
You must be an admin or owner of the account to view or generate keys.
Navigate to Settings → Integrations → Venjue API and click on »Give access«. In the modal that appears, click »Generate new token« and click the generated key to copy it.

With the key you copied, also known as your access_token, you are free to interact with the Venjue API by reading the endpoint documentation below.
The Venjue API is located at https://app.venjue.com/api/v1/.
All request must use SSL, and have the following headers:
| Header | Value |
|---|---|
| Authorization | Bearer %%2c7bcc421cbd69af84a8b9471953fcdb%%(Your access_token) |
| Content-Type | application/json |
GET /ping
Used to check if the Venjue API is reachable, responsive and authenticated successfully, so if it returns HTTP/1.1 200 OK you can be certain that the API is authenticated and ready for interaction.
{
"ping": "pong",
"meta": {
"timestamp": "2025-12-16T19:32:01Z",
"durationMs": 16.94
}
}
POST /booking
Creating a booking will effectively result in an inquiry, that upon the user's acceptance will become a booking.
The field sendNotification is a boolean to indicate if Venjue should notify the account of the incoming inquiry. If a user belonging to the account is active they will receive a notification in-app. If not, they will receive an email. You should only set this to false if they were given notice about the inquiry otherwise.
The customer.email is unique, and will tie the booking to an existing customer, if they exist.
Values for object venues, object menus, field locale and note are all optional, but will return an error if supplied but non-compliant.
Refer to the venues endpoint and menus endpoint for a list of available IDs.
{
"date": "2025-12-05",
"time": "18:00",
"title": "Demo booking",
"pax": 50,
"venues": [
{ "id": 64 },
{ "id": 88 }
],
"menus": [
{ "id": 249 }
],
"customer": {
"firstName": "Victor W.",
"lastName": "Achton",
"email": "va@venjue.dk",
"phone": "70602110"
},
"note": "Some comment pertaining to the booking",
"locale": "en_DK",
"sendNotification": true
}
{
"booking": {
"id": 2295,
"url": "%%https://app.venjue.com/booking.php?eventId=2295%%(The booking's URL in Venjue)"
}
}
Following the booking URL, Venjue will present the user with a modal to either accept or deny the inquiry and redirect to the booking.
If a booking inquiry has been accepted when following the booking URL, Venjue will present the user with the booking directly.
:::[Tip] An integration could create the booking, and then redirect the user to the returned booking URL. The user would then accept the inquiry, create the proposal and send it to their customer. The integration could then later, after the user has created the proposal, retrieve the booking to get the total price of the event and its offer status. :::
GET /booking/%%2295%%(The booking ID)
{
"booking": {
"id": 2295,
"start": { "date": "2025-12-05", "time": "18:00" },
"end": { "date": "2025-12-06", "time": "02:00" },
"title": "Demo booking",
"pax": 50,
"customer": {
"id": 25,
"billed": {
"firstName": "Victor W.",
"lastName": "Achton",
"email": "va@venjue.dk",
"phone": "70602110"
}
},
"locale": "en_DK",
"status": {
"inquiry": false,
"confirmed": false,
"cancelled": false
},
"price": 317100,
"currency": "DKK",
"payment": {
"isPending": false,
"amount": 0,
"paid": 0
},
"timestamp": {
"created": "2022-09-13 21:14:41",
"updated": "2025-12-10 15:13:50",
"sent": "2025-12-03 13:55:22",
"confirmed": "2025-12-02 12:26:12"
},
"url": "https://app.venjue.com/booking.php?eventId=2295"
}
}
The response will be binary of a PDF document with Content-Type: application/pdf and Content-Disposition: inline; filename="booking-%%2295%%(The booking ID).pdf" for storage or rendering.
Order Confirmation (or unconfirmed offer)
GET /booking/export/confirmation/%%2295%%(The booking ID)
BEO Runsheet
GET /booking/export/beo/%%2295%%(The booking ID)
Floorplan and Guestlist
GET /booking/export/floorplan/%%2295%%(The booking ID)
DELETE /booking/%%2295%%(The booking ID)
Cancelling through the API has the following prerequisites:
{ "reason": "An explanation for why the booking was cancelled" }
If the booking was succesfully cancelled, the response will be:
{
"booking": {
"cancelled": true
}
}
If the booking was not cancelled, the response will include an explanation as to why it could not be cancelled:
{
"error": {
"message": "Booking could not be cancelled",
"hint": "You cannot cancel the event, as it hasn't been confirmed"
}
}
POST /customer
A customer with the provided email must not already exist. If they do, the Venjue API will return an error.
Since a customer's email is also unique, it is beneficial to store the value of customer.email along the customer.id.
Values for object address, object business and field note are all optional, but will return an error if supplied but non-compliant.
{
"firstName": "Victor W.",
"lastName": "Achton",
"email": "va@venjue.dk",
"phone": "70602110",
"address": {
"street": "Sverigesgade 26",
"zipcode": "5000",
"city": "Odense C",
"country": "Denmark"
},
"business": {
"name": "Venjue ApS",
"vat": "42410047",
"ean": "1234567890000"
},
"note": "This is a comment pertaining to the customer"
}
{
"customer": {
"id": 25,
"url": "%%https://app.venjue.com/customers.php?customerId=25%%(The customer's URL in Venjue)"
}
}
GET /customer/%%25%%(The customer ID)
If the customer is a contact person of a business customer, the relevant data is available on customer.business.
If the account is connected to a bookkeeping system, and the customer and invoice draft have been created by Venjue, a customer.debtorId will be included. This value identifies the customer in the connected bookkeeping system.
When interacting with that bookkeeping system, you should reuse this debtorId so all financial data remains linked to the same customer and stays consistent across systems.
{
"customer": {
"id": 25,
"firstName": "Victor W.",
"lastName": "Achton",
"email": "va@venjue.dk",
"phone": "70602110",
"address": {
"street": "Sverigesgade 26",
"zipcode": "5000",
"city": "Odense C",
"country": "Denmark"
},
"business": {
"name": "Venjue ApS",
"vat": "42410047",
"ean": "1234567890000"
},
"note": "This is a comment pertaining to the customer",
"debtorId": "61553335",
"url": "https://app.venjue.com/customers.php?customerId=25"
}
}
DELETE /customer/%%25%%(The customer ID)
Deleting a customer will not affect their billing data on bookings, but rather the collection of associated bookings and the customer's ratings, notes, feedback answers and more. The customer's billing data will remain on affected bookings.
GET /menus
{
"menus": [
{
"id": 249,
"name": "Some menu"
},
{
"id": 819,
"name": "Another menu"
}
]
}
GET /venues
{
"venues": [
{
"id": 64,
"name": "Some venue"
},
{
"id": 88,
"name": "Another venue"
}
]
}
The Venjue API returns error codes compliant with the HTTP standard with no deviation. You can always rely on the codes conforming to the below explanation table, and the JSON returned will have a more detailed explanation.
| Code | Description |
|---|---|
| 200 | Success! |
| 400 | A bad request made by the client, such as a malformed or a non-compliant JSON body. |
| 401 | Unauthorized request, meaning the client's authorization_token is expired, not valid, or subscription tier does not allow API access. |
| 403 | The client's request could not performed. |
| 404 | The resource requested by the client was not found. |
| 405 | The method was not allowed for the requested endpoint. |
| 409 | The client's request could not performed, because it is conflicting with the current data and actions available. |
| 415 | The client's request was not made with a JSON body. |
| 500 | An internal server error occured with the Venjue API. A Log ID for debugging is returned to the client. |
Error responses from the Venjue API will always be in JSON and contains the HTTP error code, a message and hint, as well as metadata about the client's request.
In this example the request body's date format (among other things) are wrong, and thus triggered the 400 error and corresponding message.
{
"error": {
"code": 400,
"message": "Invalid format at date",
"hint": "Inspect the error.message for details as to what might have went wrong. Check the API documentation for what is expected for method 'POST' at the endpoint '/api/v1/booking' on https://venjue.com/docs/#article-api",
"request": {
"method": "POST",
"resource": "booking",
"identifier": null,
"parameters": [],
"contentType": "application/json",
"body": {
"date": "January 1st 2026",
"time": "6 o'clock",
"pax": "6 gremlins"
}
}
}
}
If an internal server error happens (5xx), a Log ID will be provided for debugging on our end.
If any required data is missing, the data is not compliant, or if unsupported fields are submitted, the API will return an error along with the incorrect data, and the type and value it should have to be valid in the error.message along with some further info in error.hint.
Any endpoint that requires a request body will inform about all missing required fields. Simply perform the request without a body to get the full list in error.message:
{
"error": {
"code": 400,
"message": "Missing required fields: date, time, title, pax, customer",
"hint": "Inspect the error.message for details as to what might have went wrong. Check the API documentation for what is expected for method 'POST' at the endpoint '/api/v1/booking' on https://venjue.com/docs/#article-api",
[...]
}
}
If a field is not valid, the error.message will contain why:
{
"error": {
"code": 400,
"message": "Invalid body. Expected object at customer",
"hint": "Inspect the error.message for details as to what might have went wrong. Check the API documentation for what is expected for method 'POST' at the endpoint '/api/v1/booking' on https://venjue.com/docs/#article-api",
[...]
}
}
To begin interacting with Venjue via our external API, we provide an OAuth-like integration flow for third party developers who want to build direct integrations for shared customers, which makes it easier for the user to connect with the Venjue API from your product, and presents your integration in a more professional and less technical way.
Create an account for Venjue, as if you were an actual customer. It is important that you use a valid VAT/Danish CVR that you have the neccessary permission to register for. The account will automatically be on the free trial of our Enterprise plan with API access. This account will act both as an account you use to test your integration's functionality, and also as the owner of your client_secret for actual users of the integration.
client_secretVenjue uses an OAuth-like flow; the client_secret is an API key created in the UI.
Login to Venjue and navigate to Settings → Integrations → Venjue API and click on »Give access«. In the modal that appears, click »Generate new token« and click the generated key to copy it, like instructed as if you were a customer: Generate a key.
The generated key will act as your official integration's client_secret, and from hereon out this account is the owner of the client_secret all users of your integration will rely on.
:::danger[Keep the key intact!]
If you later delete the key that acted as your integration's client_secret, you will break the authentication for existing and future users of your integration. Please take note of it now, so you do not confuse it with other keys.
:::
Set your integration's icon, name and FQDN (fully qualified domain name, e.g. 'venjue.com'), which will be presented to users of the integration.
The app.iconUrl field must be a URL to a .png file with square dimensions at least 128 by 128 pixels.
The app.name must be only letters, and between 5 and 15 characters.
The app.name and app.iconUrl icon will both be presented to users of your integration, so it is important to give a good first impression when selecting a name and icon.
The app.fqdn is used to limit the redirect_uri in the next step to your domain only.
curl -X PUT https://api.venjue.com/api/v1/auth/register \
-H "Authorization: Bearer %%client_secret%%(Provide your integration client_secret obtained from previous step)" \
-H "Content-Type: application/json" \
-d '{
"app": {
"name": "A short, but indicative name for your integration",
"fqdn": "venjue.com",
"iconUrl": "https://venjue.com/assets/icon.png"
}
}'
You should GET /api/v1/auth/register to see your current integration data. Please note the client_id, which will be used for the next step.
From your product, when the user decides to integrate with Venjue, you should redirect them to https://app.venjue.com/apiApproveIntegration.php with the following url-encoded parameters:
| Parameter | Value |
|---|---|
| client_id | The client_id belonging to the Venjue account that owns the integration (obtained from the previous step). |
| redirect_uri | The URI Venjue should redirect to after the user approves the integration, which will have the auth_code returned. Please note, that the redirect_uri must belong to the FQDN submitted in the previous step. |
Venjue will then present the user with an approval page that has the name and icon of your integration, where they can grant or deny access.
If access was granted, a short-lived auth_code will be issued on behalf of the user's account and they will be redirected to the supplied redirect_uri with the auth_code parameter prepended.
These are the returned parameters, after Venjue redirects to the redirect_uri:
| Parameter | Value |
|---|---|
| auth_code | The issued short-lived auth_code, if user granted permission. |
| user_accepted | Either true or false, depending on the user's action on the approval page. |
| error_message | Will contain an error message, if any part of the integration's app data or this redirect are faulty. Used for debugging, and should not be presented to the user. |
auth_code for an access_tokenThe integration should then exchange the short-lived auth_code obtained in the previous step for a permanent access_token immediately.
The returned access_token will be used for subsequent requests to the Venjue API on behalf of the user.
curl -X POST https://api.venjue.com/api/v1/auth/token \
-H "Authorization: Bearer %%client_secret%%(Provide your integration client_secret)" \
-H "Content-Type: application/json" \
-d '{
"client_id": %%client_id%%(Provide your integration client_id),
"auth_code": "%%auth_code%%(Provide the account auth_code returned from previous step)"
}'
{
"auth/token": {
"access_token": "%%access_token%%(The permanent access_token)"
}
}
Your Venjue account is the owner of the client_secret but now also the owner of an access_token generated by your integration for testing purposes. This might seem a bit confusing, since you are now acting as both the customer while testing and the integration partner. You are free to delete the key that is your testing access_token, if you want to reroll it. You can manage both in Venjue as in step 2.
access_token to make requests to the API's endpointsFinally, to ensure that the connection was established, and that the access_token is valid for future use on behalf of the user account, the integration should GET /api/v1/ping with a header value of Authorization: Bearer %%access_token%%(The account access_token from the previous step) and check for HTTP/1.1 200 OK.
If successful, the integration for the user is now complete, and the integration should then present the user with a success message.
The integration stores the access_token and uses it for subsequent requests to the Venjue API.
Users on Venjue are free to revoke your integration's API access, so it makes sense to use the ping endpoint to check the authorization proactively before trying to interact with the Venjue API.
You can now continue to read about our endpoints to start developing the functionalities of your integration.
Contact us at hello@venjue.com to get your integration present on Venjue's list of integration partners.
We're eager to learn about your integration, and will gladly listen to any ideas for the Venjue API's further development to better accomodate your needs.
API access requires an active subscription to either the Enterprise plan or Enterprise Add-On plan, or an active trial period. ↩︎
Didn't find what you were looking for?
Contact us to get additional help, suggest changes or additions, or if you have further questions