> For the complete documentation index, see [llms.txt](https://wavatec.gitbook.io/ninoxbee/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wavatec.gitbook.io/ninoxbee/create-first-form.md).

# Create first form

In order to get your first form up and running, you will need to implement a few functions inside your ninox database.

### saveOrUpdateForm

In order to perform updates to your ninox database, Ninoxbee needs a few information so that all its interactions with your ninox instance is bound to the context of that database.

The mandatory fields needed are&#x20;

* The **Host** on which your instance is running. Use app.ninoxdb.com for public cloud databases.
* The **API Key** to perform updates on your database
* The **TeamId** in which your database is installed
* The **DatabaseId** of the application in which you will be performing updates.

Ninoxbee allows you to define a few other extra skinning variables. The code block below shows all the possible values for the form creation api call to ninoxbee.

*Adjust the function below to externalise settings into a settings table*

```javascript
function saveOrUpdateForm(form:Form) do
	let _ninoxHost := "anastasia.ninoxdb.com";
	let _ninoxApiKey := "YOUR_NINOX_API_KEY";
	let _captchaProtect := false;
	let _teamId := teamId();
	let _databaseId := databaseId();
	let _askUntilDate := date(2024,1,1);
	let _startAcceptingDate := today();
	let _ninoxbeeHost := "https://app.ninoxbee.com";	
	let _body := {
			host: _ninoxHost,
			apiKey: _ninoxApiKey,
			teamId: _teamId,
			databaseId: _databaseId,
			introFn: "_myIntroFn",
			initFn: "_myInitSessionFn",
			summaryFn: "_myGetSummary",			
			nextFn: "_myGetNextQuestionFn",
			prevFn: "_myGetPreviousQuestionFn",
			answerFn: "_myAnswerQuestionFn",
			buttonTextFn: "_myButtonTextFn",
			captcha: _captchaProtect,
			pinCode: "" + a.'Pin Code',
			askUntil: "" + format(_askUntilDate, "YYYY-MM-DD"),
			enabled: true,
			startDate: "" + format(_startAcceptingDate, "YYYY-MM-DD"),
			introImgUrl: "URL TO A PUBLIC IMAGE TO DISPAY ON INTRO SCREEN",
			basicSkinning: {
				logoUrl: "URL TO FORM LOGO,
				headerTitle: "TITLE OF THE FORM IN HEADER",
				headerBgColor: "#000000",
				headerFgColor: "#FFFFFF"
			},
			languages: [{
					code: "fr",
					name: "Français",
					languageOrder: 1
				}],
			advancedSkinning: null,
			formExpiredMessage: "This form has expired,
			pincodeErrorMessage: "Invalid pincode",
			formNotOpenYetMessage: "Form not open",
			formNotPublishedMessage: "For not published"
		};
	if form._FORM_ID = null then
		let response := do as server
				http("POST", _ninoxbeeHost + "/api/v1/forms", {
					'x-auth': "_YOUR_NINOXBEE_APIKEY",
					'content-type': "application/json"
				}, _body)
			end;
		a.(_FORM_ID := response.result.result.uuid);
		a.(_FORM_URL := response.result.result.publicUrl)
	else
		let response := do as server
				http("PUT", nbHost() + "/api/v1/forms/" + a._FORM_ID, {
					'x-auth': s.'Ninoxbee Api Key',
					'content-type': "application/json"
				}, _body)
			end;
		void
	end
end;
```

## introFn and initFn

This function is responsible of rendering the first card or the landing screen card. It is displayed **after** the captcha protection.

```javascript
function introFn(form_id : text,language : text) do
	{
		title: "Title for your form based on form_id and language",
		description: "Intro text based for _form_id and language"
	}
end
	
```

When this function is invoked by ninoxBee, a card shows on ninoxbee portal displaying the title and the description as well as a **start** button. Hitting the start button invokes a call on ninox which generates a **session** object in which all future interactions will be attached.

```javascript
function initSession(_formId : text) do
	{
		submissionId: "5bb24177-8d80-4c11-b5bf-7d103f49a319"
	}
end;
```

The submissionId returned above should be generated by your ninox database. It will be submitted by ninoxbee automatically for all the remaining calls. Using this submissionId you should be able to identify which user is attached to this form and submit the answers to the correct record.

### Ninoxbee ninox app

Open the downloaded Ninoxbee app from your workspace, and start configuring your API Key. The API key can be found in your Ninoxbee Portal.

<figure><img src="https://4247521372-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrFPjZvDUFTV1LBmDQQm2%2Fuploads%2FQRPYqxBfZketIIIyAJl4%2Fimage.png?alt=media&amp;token=9b4d697c-1dc1-4a9f-847d-112cd9f1be46" alt=""><figcaption><p>Register your new Key in Ninoxbee Ninox app</p></figcaption></figure>

One you've registered your key, click on the key line. The app will automatically retrieve all active forms for that Api-key.&#x20;

<figure><img src="https://4247521372-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrFPjZvDUFTV1LBmDQQm2%2Fuploads%2FmTO7JnGI7zvSUQvw89w2%2Fimage.png?alt=media&amp;token=2af78169-be61-4e91-883c-f2a314741565" alt=""><figcaption><p>Forms attached the api key</p></figcaption></figure>

In the **Key** view, you can preview the attached forms and **Manage your Stripe subscription page.**

Create a new form or click on an existing form.

<figure><img src="https://4247521372-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrFPjZvDUFTV1LBmDQQm2%2Fuploads%2FawOuvmOsOu0buygmnSIs%2Fimage.png?alt=media&amp;token=fdf09812-e7b9-4614-acf7-e9c1bedc81c4" alt=""><figcaption><p>New form creation</p></figcaption></figure>

A form in Ninoxbee is a scafolding object for generating forms dynamically from your Ninox database. Give your form a title and hit **Save**. Ninoxbee assigns you a unique ID and a URL to access that form.

<figure><img src="https://4247521372-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FrFPjZvDUFTV1LBmDQQm2%2Fuploads%2FQB9OAOf53zznfXnUtfNM%2Fimage.png?alt=media&amp;token=030fcbe2-3d5f-41b4-8e03-7716a509c083" alt=""><figcaption><p>A unique ID is auto-generated for your form</p></figcaption></figure>

At this stage of the process your form is still <mark style="color:red;">not accessible</mark>; clicking on the generated link should return you a "The form is not published yet" error page.

Ninoxbee features an **Intro view** securely hosted within its configuration. For enhanced security, API calls to your Ninox database are initiated only after successful completion of the captcha challenge on your form.

The following table lists the available options to get your form up and running

<table><thead><tr><th width="140">Field</th><th width="322">Description</th><th width="174">Options</th><th data-type="checkbox">Required</th></tr></thead><tbody><tr><td><strong>Title</strong></td><td>The title of the form which appears on the top bar of the page.</td><td>Text</td><td>true</td></tr><tr><td>Password Protection</td><td>Whether this form is protected or fully public</td><td><strong>None :</strong> The form is not protected<br><strong>Pin</strong> : The form is protected by a unique Pin code<br><strong>OTP</strong> : The form is protected by an OTP Pin code sent to the end user directly</td><td>false</td></tr><tr><td>Pincode Error Message</td><td>The error message that should show up if pin was incorrectly set</td><td>Required if a protection is set</td><td>false</td></tr><tr><td>Captcha</td><td>Protect abuse of this form by enforcing the end user to solve a Captcha question</td><td>true | false</td><td>false</td></tr><tr><td>Start accepting submissions from</td><td>The starting date for accepting answers on this form. Leave blank to start accepting answers as soon as form is <em>published</em></td><td>Datetime</td><td>false</td></tr><tr><td>Ask Until</td><td>The date after which the form should be considered closed for <em>answers.</em> Leave blank for never ending acceptance forms</td><td>Datetime</td><td>false</td></tr><tr><td><strong>Published</strong></td><td>Whether the form is published or not.</td><td>true | false</td><td>false</td></tr><tr><td>Form not open yet message</td><td>The message that should appear in case form is not yet open</td><td>Text</td><td>false</td></tr><tr><td>Form Expired message</td><td>The message that should appear in case form has expired</td><td>Text</td><td>false</td></tr><tr><td>Form not published yet message</td><td>The message that should appear if the form is not published</td><td>Text</td><td>false</td></tr><tr><td>Intro Image</td><td>Cover image of the form. Appears before the first question is asked and before the captcha is solved (no api calls to your ninox instance at this stage).</td><td>Image</td><td>false</td></tr><tr><td><strong>Intro Title</strong></td><td>Cover image of the form. Appears before the first question is asked and before the captcha is solved (no api calls to your ninox instance at this stage).</td><td>Text</td><td>true</td></tr><tr><td><strong>Host</strong></td><td>The host on which your ninox database is hosted</td><td>Text</td><td>true</td></tr><tr><td><strong>Ninox API Key</strong></td><td>The API key to invoke actions on your ninox database</td><td>Text</td><td>true</td></tr><tr><td><strong>TeamId</strong></td><td>The teamId on which your business ninox database is hosted</td><td>Text</td><td>true</td></tr><tr><td><strong>DatabaseId</strong></td><td>The database id of your ninox business app</td><td>Text</td><td>true</td></tr><tr><td><strong>Init Session function name *</strong></td><td>Name of the function in your business app that will 'init' the session</td><td>Text</td><td>true</td></tr><tr><td><strong>Next question function name *</strong></td><td>Name of the function in your business app that will fetch the next question based on a current questionId</td><td>Text</td><td>true</td></tr><tr><td><strong>Previous question function name *</strong></td><td>Name of the function in your business app that will fetch the previous question based on a current questionId</td><td>Text</td><td>true</td></tr><tr><td><strong>Answer function name *</strong></td><td>Name of the function in your business app that will receive the answer from Ninoxbee and fetch the next question</td><td>Text</td><td>true</td></tr><tr><td>Logo File</td><td>Image of the logo appearing on the top left side of the form</td><td>Image</td><td>false</td></tr><tr><td>Background color</td><td></td><td>Color</td><td>false</td></tr><tr><td>Foreground color</td><td></td><td>Color</td><td>false</td></tr></tbody></table>

Now that you've configured your forms let's take a look at the 4 main function you need to implement in your app to interact with this form.
