Project form
Every community has a project form: the questionnaire that each of its projects fills in, on top of the built-in project profile fields. On this page we'll dive into the endpoints you use to define that form's questions, and into the way an application definition reuses those same questions so applicants answer them once.
How the project form fits together
A community is created with exactly one default project form, and it starts out empty. That form is the community's project profile questionnaire — read it and write it through GET and PUT /api/Community/{id}/ProjectForm.
A form is an ordered list of questions, which you may group into ordered sections. Each question carries an answer type, its ordering, a privacy level that decides who sees the answer, and — for the choice types — an ordered list of options. Every project that belongs to the community answers this one form, and its answers are stored per community: a project that belongs to three communities keeps three independent sets of answers. Reading and writing those answers is covered on the Projects page.
A community can also hold additional project forms beyond the default one, managed through the /api/ProjectForm endpoints. These exist so that an application round can collect a different set of project questions from its applicants. They use the identical question model, and they are never the community's live profile form.
These endpoints are community administration endpoints — plan on calling them as an administrator of the community that owns the form.
Answer types
answerType is sent as an integer and decides how a question is answered.
| Value | Type | Notes |
|---|---|---|
0 | Radio choice | Single choice. Requires questionOptions. |
1 | Checkbox choice | Multiple choice. Requires questionOptions. |
2 | Dropdown choice | Single choice. Requires questionOptions. |
3 | Multiple choice | Multi-select. Requires questionOptions. |
4 | Money | A monetary amount. |
5 | Calendar | A date. |
7 | Short text | Single-line free text. |
8 | Long text | Rich/multi-line free text. |
9 | File | A file upload. |
10 | Scale | A numeric rating on a scale. |
11 | Country | A country picker. |
12 | Table | A grid of cells. |
13 | Numeric | A plain number. |
The negative values are project fields: questions that read and write one of the project's built-in profile attributes instead of storing a separate answer. Add one to the form when you want that attribute collected alongside the rest of the questionnaire.
| Value | Project field | Value | Project field |
|---|---|---|---|
-1 | Logo | -8 | Development stage |
-2 | Cover image | -9 | Industry / category |
-4 | LinkedIn URL | -10 | Country |
-5 | Facebook URL | -11 | City |
-6 | Website URL | -12 | Description |
-7 | Sustainable Development Goals | -13 | Name |
Questions returned by the API carry a computed isProjectField flag, which is true for exactly these types. 6 and -3 are not assigned.
Question privacy levels
privacyLevel is sent as an integer and decides who can see a project's answer to that question.
| Value | Level | Who sees the answer |
|---|---|---|
0 | Undefined | Unset. Treat as public. |
1 | Public | Anyone who can see the project. |
2 | Community | Approved members of the community. |
3 | Team | The project's team only. |
4 | Custom | Only the circles listed in privacyCirclesIds. |
5 | Team and mentors | The project's team plus its mentors. |
6 | Set by team | The project's team chooses the level itself. |
Conditional visibility
A question can be shown only when other answers on the same form match a set of rules. conditionalLogicType is 0 none, 1 show when any rule matches, 2 show only when all rules match. Each rule in formQuestionConditionalLogicList names another question on the same form and compares it with conditionLogic: 1 equal, 2 not equal, 3 greater than, 4 less than, 5 contains, 6 does not contain, 7 is empty, 8 is not empty.
Get the community project form
This endpoint allows you to retrieve a community's default project form — every question its projects answer, with the sections and options that go with them.
Path parameters
- Name
id- Type
- integer
- Description
Required. The ID of the community whose project form you want.
Response attributes
- Name
id- Type
- integer
- Description
The ID of the form.
- Name
name- Type
- string
- Description
The form name. The community's default project form is named
Projects.
- Name
description- Type
- string
- Description
A description of the form.
- Name
communityId- Type
- integer
- Description
The ID of the community the form belongs to.
- Name
creationDate- Type
- string | null
- Description
When the form was created (ISO 8601).
- Name
lastEditionDate- Type
- string | null
- Description
When the form was last edited (ISO 8601).
- Name
userCreatorId- Type
- integer
- Description
The ID of the user who created the form.
- Name
includeInLandingPage- Type
- boolean
- Description
Whether the community's public landing page shows its projects section.
- Name
isDefaultCommunityProjectForm- Type
- boolean
- Description
Whether this is the community's live project profile form. Always
trueon this endpoint.
- Name
sections- Type
- array
- Description
The form's sections, ordered by
order. Described undersectionsarray items below.
- Name
questions- Type
- array
- Description
The form's questions, ordered by
questionOrder. Described underquestionsarray items below.
sections array items
- Name
id- Type
- integer
- Description
The ID of the section.
- Name
title- Type
- string
- Description
The section heading.
- Name
description- Type
- string
- Description
The section's introductory text.
- Name
order- Type
- integer
- Description
The section's position on the form.
questions array items
- Name
id- Type
- integer
- Description
The ID of the question. This is the ID you link an application question to, and the ID a project's answers are keyed by.
- Name
title- Type
- string
- Description
The question's label in the form editor.
- Name
description- Type
- string
- Description
Help text shown under the question. May contain HTML.
- Name
question- Type
- string
- Description
The prompt shown to the person answering.
- Name
questionOrder- Type
- integer
- Description
The question's position on the form, or within its section.
- Name
sectionId- Type
- integer | null
- Description
The section the question belongs to.
nullwhen the question is not in a section.
- Name
answerType- Type
- integer
- Description
How the question is answered. See Answer types above.
- Name
isProjectField- Type
- boolean
- Description
Whether this question maps to a built-in project attribute —
truefor the negative answer types.
- Name
mandatoryAnswer- Type
- boolean
- Description
Whether an answer is required.
- Name
editableAnswer- Type
- boolean
- Description
Whether the project may change its answer after answering once.
- Name
allowMultipleAnswer- Type
- boolean
- Description
Whether more than one value may be given.
- Name
questionOptions- Type
- array
- Description
The selectable options, ordered by
questionOptionOrder. Only populated for the choice answer types. Described underquestionOptionsarray items below.
- Name
questionLinks- Type
- array
- Description
Reference links attached to the question. Each item is an object with a single
questionLinkstring.
- Name
isFilterable- Type
- boolean | null
- Description
Whether the community's project list can be filtered by this question's answer. Meaningful for the country and choice answer types.
- Name
privacyLevel- Type
- integer
- Description
Who can see the answer. See Question privacy levels above.
- Name
privacyCirclesIds- Type
- array of integer
- Description
The circle IDs allowed to see the answer. Only meaningful when
privacyLevelis4(Custom).
- Name
conditionalLogicType- Type
- integer
- Description
Whether the question is conditionally shown, and how its rules combine. See Conditional visibility above.
- Name
formQuestionConditionalLogicList- Type
- array
- Description
The visibility rules. Each item carries
id,conditionFormQuestionId(another question on this form),conditionLogic, and eitherformQuestionOptionIdorcustomValueas the value to compare against.
- Name
questionType- Type
- integer
- Description
When the question is asked:
0as part of the project profile,1only once the project has been approved into the community.
- Name
includeInProjectProfile- Type
- boolean
- Description
Whether the answer is shown on the project's profile.
- Name
hasLimit- Type
- boolean
- Description
Whether a length limit applies. Text answer types only.
- Name
limitType- Type
- integer
- Description
The unit of the limit:
1characters,2words.
- Name
limitValue- Type
- integer | null
- Description
The maximum allowed by the limit.
- Name
defaultProjectFormQuestionId- Type
- integer | null
- Description
The question on the community's default project form that this question mirrors. Always
nullhere — see Mirroring a round question onto the default form below.
Request
curl -X GET https://api.babele.co/api/Community/999/ProjectForm \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJleGFtcGxlIiwiZXhwIjoxNzQzODY1MjA3fQ.DEMO_SIGNATURE_NOT_A_REAL_TOKEN" \
-H "Content-Type: application/json"
Response
{
"id": 1258,
"name": "Projects",
"description": "Project profile questions",
"communityId": 999,
"creationDate": "2023-05-23T14:19:16.203812Z",
"lastEditionDate": "2024-12-16T23:56:29.628361Z",
"userCreatorId": 398964,
"includeInLandingPage": true,
"isDefaultCommunityProjectForm": true,
"sections": [
{
"id": 42,
"title": "About your startup",
"description": "",
"order": 0
}
],
"questions": [
{
"id": 781,
"title": "Elevator pitch",
"description": "<p>One sentence describing what you do.</p>",
"question": "Tell us about your startup",
"questionOrder": 0,
"sectionId": 42,
"answerType": 8,
"isProjectField": false,
"mandatoryAnswer": true,
"editableAnswer": true,
"allowMultipleAnswer": false,
"questionOptions": [],
"questionLinks": [],
"isFilterable": null,
"privacyLevel": 1,
"privacyCirclesIds": [],
"conditionalLogicType": 0,
"formQuestionConditionalLogicList": [],
"questionType": 0,
"includeInProjectProfile": true,
"hasLimit": true,
"limitType": 2,
"limitValue": 150,
"defaultProjectFormQuestionId": null
},
{
"id": 782,
"title": "Stage",
"description": "",
"question": "What stage is your startup at?",
"questionOrder": 1,
"sectionId": 42,
"answerType": 0,
"isProjectField": false,
"mandatoryAnswer": true,
"editableAnswer": true,
"allowMultipleAnswer": false,
"questionOptions": [
{ "id": 900, "questionOption": "Idea", "questionOptionOrder": 0 },
{ "id": 901, "questionOption": "MVP", "questionOptionOrder": 1 },
{ "id": 902, "questionOption": "Revenue", "questionOptionOrder": 2 }
],
"questionLinks": [],
"isFilterable": true,
"privacyLevel": 1,
"privacyCirclesIds": [],
"conditionalLogicType": 0,
"formQuestionConditionalLogicList": [],
"questionType": 0,
"includeInProjectProfile": true,
"hasLimit": false,
"limitType": 1,
"limitValue": null,
"defaultProjectFormQuestionId": null
}
]
}
Update the community project form
This endpoint allows you to define the community's project form: add, edit, reorder and remove its questions, options and sections. It responds with the saved form, in the same shape as the get endpoint above.
This is a snapshot write, not a patch. When you send a questions array it
replaces the question set: entries with an id of 0 are created,
entries whose id matches an existing question are updated in place, and
any existing question you leave out is deleted, together with every
answer projects have already given to it. Read the form first, change
what you need, and send the whole thing back. Sections behave the same way.
Leaving questions out of the body entirely — or sending null — leaves the existing questions untouched. Sending [] deletes all of them. The same applies to sections.
Path parameters
- Name
id- Type
- integer
- Description
Required. The ID of the community whose project form you are updating.
Request body attributes
- Name
communityId- Type
- integer
- Description
The ID of the community. Send the same value as the path parameter.
- Name
includeInLandingPage- Type
- boolean
- Description
Whether the community's public landing page shows its projects section.
- Name
sections- Type
- array
- Description
The complete set of sections. Described under
sectionsarray items below.
- Name
questions- Type
- array
- Description
The complete set of questions. Described under
questionsarray items below.
sections array items
- Name
id- Type
- integer
- Description
0creates a new section. Any other value must be the ID of a section already on this form, or the request is rejected.
- Name
title- Type
- string
- Description
Required. The section heading. It may not be blank.
- Name
description- Type
- string
- Description
The section's introductory text.
- Name
order- Type
- integer
- Description
Required. The section's position. Every section in one request must have a distinct
order.
questions array items
Takes the same fields as the questions items of the get endpoint above, minus the computed isProjectField. The ones that change meaning on the write path:
- Name
id- Type
- integer
- Description
0creates a new question. Anidthat matches an existing question on this form updates it in place.
- Name
title- Type
- string
- Description
Required. The question's label in the form editor.
- Name
question- Type
- string
- Description
The prompt shown to the person answering. Required for every answer type except the project fields, which take their prompt from the attribute they map to.
- Name
questionOrder- Type
- integer
- Description
Required. Keep the values distinct — ties are broken arbitrarily.
- Name
answerType- Type
- integer
- Description
Required. See Answer types above.
- Name
questionOptions- Type
- array
- Description
Required, and non-empty, for the four choice answer types; leave it out for the others. Each item takes
id(0to create),questionOptionandquestionOptionOrder. Options are diffed the same way as questions — an option you leave out is deleted, and so are the answers pointing at it.
- Name
sectionId- Type
- integer | null
- Description
The section this question belongs to.
nullleaves it uncategorised. To place a question in a section you are creating in the same request, set this to that section'sordervalue; the API resolves it to the new section's ID once it is saved.
- Name
formQuestionConditionalLogicList- Type
- array
- Description
The visibility rules. Every
conditionFormQuestionIdmust be a question that exists on this same form, or the request is rejected.
- Name
privacyCirclesIds- Type
- array of integer
- Description
The circles that may see the answer. Only applied when
privacyLevelis4(Custom).
Possible errors
- Name
401 Unauthorized- Description
The request is missing valid authentication.
- Name
404 Not Found- Description
No community project form matches
id.
- Name
500 Internal Server Error- Description
The body failed validation — a blank section title, two sections sharing an
order, asectionIdorconditionFormQuestionIdthat is not on this form, or an invalid conditional-logic value.
Request
curl -X PUT https://api.babele.co/api/Community/999/ProjectForm \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJleGFtcGxlIiwiZXhwIjoxNzQzODY1MjA3fQ.DEMO_SIGNATURE_NOT_A_REAL_TOKEN" \
-H "Content-Type: application/json" \
-d '{"communityId":999,"includeInLandingPage":true,"sections":[{"id":42,"title":"About your startup","description":"","order":0}],"questions":[{"id":781,"title":"Elevator pitch","question":"Tell us about your startup","questionOrder":0,"sectionId":42,"answerType":8,"mandatoryAnswer":true,"editableAnswer":true,"privacyLevel":1,"conditionalLogicType":0,"hasLimit":true,"limitType":2,"limitValue":150},{"id":0,"title":"Team size","question":"How many people work on this full time?","questionOrder":1,"sectionId":42,"answerType":13,"mandatoryAnswer":false,"editableAnswer":true,"privacyLevel":2,"conditionalLogicType":0}]}'
Response
{
"id": 1258,
"name": "Projects",
"communityId": 999,
"lastEditionDate": "2026-08-07T10:12:44.881204Z",
"userCreatorId": 398964,
"includeInLandingPage": true,
"isDefaultCommunityProjectForm": true,
"sections": [
{ "id": 42, "title": "About your startup", "description": "", "order": 0 }
],
"questions": [
{
"id": 781,
"title": "Elevator pitch",
"question": "Tell us about your startup",
"questionOrder": 0,
"sectionId": 42,
"answerType": 8,
"isProjectField": false,
"mandatoryAnswer": true,
"editableAnswer": true,
"questionOptions": [],
"privacyLevel": 1,
"privacyCirclesIds": [],
"conditionalLogicType": 0,
"formQuestionConditionalLogicList": [],
"questionType": 0,
"includeInProjectProfile": true,
"hasLimit": true,
"limitType": 2,
"limitValue": 150,
"defaultProjectFormQuestionId": null
},
{
"id": 1043,
"title": "Team size",
"question": "How many people work on this full time?",
"questionOrder": 1,
"sectionId": 42,
"answerType": 13,
"isProjectField": false,
"mandatoryAnswer": false,
"editableAnswer": true,
"questionOptions": [],
"privacyLevel": 2,
"privacyCirclesIds": [],
"conditionalLogicType": 0,
"formQuestionConditionalLogicList": [],
"questionType": 0,
"includeInProjectProfile": true,
"hasLimit": false,
"limitValue": null,
"defaultProjectFormQuestionId": null
}
]
}
List a community's other project forms
This endpoint allows you to list the extra project forms a community keeps for its application rounds. The community's default project form is not included — fetch that one through GET /api/Community/{id}/ProjectForm.
Query parameters
- Name
communityId- Type
- integer
- Description
The ID of the community whose forms you want. Send it explicitly; without it the call is not scoped to any community and returns nothing useful.
Response attributes
- Name
count- Type
- integer
- Description
The number of forms returned.
- Name
list- Type
- array
- Description
The forms, each in the same shape as the response of
GET /api/Community/{id}/ProjectForm, withisDefaultCommunityProjectFormalwaysfalse.
- Name
filters- Type
- null
- Description
Not used by this endpoint.
Request
curl -X GET "https://api.babele.co/api/ProjectForm/GetAll?communityId=999" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJleGFtcGxlIiwiZXhwIjoxNzQzODY1MjA3fQ.DEMO_SIGNATURE_NOT_A_REAL_TOKEN" \
-H "Content-Type: application/json"
Response
{
"count": 1,
"filters": null,
"list": [
{
"id": 4501,
"name": "Accelerator intake — project questions",
"description": "",
"communityId": 999,
"creationDate": "2026-01-10T10:00:00Z",
"lastEditionDate": "2026-01-10T10:00:00Z",
"userCreatorId": 398964,
"isDefaultCommunityProjectForm": false,
"includeInLandingPage": false,
"sections": [],
"questions": []
}
]
}
Create a project form
This endpoint allows you to create an additional project form for a community — the kind you attach to an application round so it collects a different set of project questions. It responds with the created form.
Do not use this to create a community's profile form. Every community
already has exactly one, created with the community itself; leave
isDefaultCommunityProjectForm unset here.
Request body attributes
- Name
name- Type
- string
- Description
Required. The form's name.
- Name
description- Type
- string
- Description
A description of the form.
- Name
communityId- Type
- integer
- Description
Required. The ID of the community the form belongs to.
- Name
questions- Type
- array
- Description
The form's questions. Same shape as the
questionsitems ofPUT /api/Community/{id}/ProjectFormabove.
- Name
sections- Type
- array
- Description
The form's sections. Same shape as the
sectionsitems above.
Request
curl -X POST https://api.babele.co/api/ProjectForm \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJleGFtcGxlIiwiZXhwIjoxNzQzODY1MjA3fQ.DEMO_SIGNATURE_NOT_A_REAL_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Accelerator intake — project questions","description":"","communityId":999,"sections":[],"questions":[{"id":0,"title":"Traction","question":"What traction do you have so far?","questionOrder":0,"answerType":8,"mandatoryAnswer":true,"editableAnswer":true,"privacyLevel":2,"conditionalLogicType":0}]}'
Response
{
"id": 4501,
"name": "Accelerator intake — project questions",
"description": "",
"communityId": 999,
"creationDate": "2026-08-07T10:20:03.114882Z",
"lastEditionDate": "2026-08-07T10:20:03.114882Z",
"userCreatorId": 398964,
"isDefaultCommunityProjectForm": false,
"includeInLandingPage": false,
"sections": [],
"questions": [
{
"id": 8001,
"title": "Traction",
"question": "What traction do you have so far?",
"questionOrder": 0,
"answerType": 8,
"isProjectField": false,
"mandatoryAnswer": true,
"editableAnswer": true,
"questionOptions": [],
"privacyLevel": 2,
"privacyCirclesIds": [],
"conditionalLogicType": 0,
"formQuestionConditionalLogicList": [],
"questionType": 0,
"includeInProjectProfile": true,
"defaultProjectFormQuestionId": null,
"sectionId": null
}
]
}
Get a project form
This endpoint allows you to retrieve any project form by its own ID — a community's default form or one of its round forms. The response is the same shape as GET /api/Community/{id}/ProjectForm.
Path parameters
- Name
id- Type
- integer
- Description
Required. The ID of the form.
Possible errors
- Name
404 Not Found- Description
No form matches
id.
Request
curl -X GET https://api.babele.co/api/ProjectForm/4501 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJleGFtcGxlIiwiZXhwIjoxNzQzODY1MjA3fQ.DEMO_SIGNATURE_NOT_A_REAL_TOKEN" \
-H "Content-Type: application/json"
Response
{
"id": 4501,
"name": "Accelerator intake — project questions",
"communityId": 999,
"isDefaultCommunityProjectForm": false,
"sections": [],
"questions": [
{
"id": 8001,
"title": "Traction",
"question": "What traction do you have so far?",
"questionOrder": 0,
"answerType": 8,
"isProjectField": false,
"mandatoryAnswer": true,
"privacyLevel": 2,
"questionOptions": [],
"defaultProjectFormQuestionId": null,
"sectionId": null
}
]
}
Update a project form
This endpoint allows you to update any project form by its own ID. It takes the same body as PUT /api/Community/{id}/ProjectForm — including the same snapshot-write semantics for questions, questionOptions and sections — and additionally applies name and description.
Use this endpoint for a round's project form. For a community's profile form, prefer PUT /api/Community/{id}/ProjectForm, which does not need you to look the form ID up first.
Path parameters
- Name
id- Type
- integer
- Description
Required. The ID of the form.
Request body attributes
- Name
name- Type
- string
- Description
The form's name.
- Name
description- Type
- string
- Description
A description of the form.
- Name
communityId- Type
- integer
- Description
The ID of the community the form belongs to.
- Name
questions- Type
- array
- Description
The complete set of questions. Omit to leave them untouched; send
[]to delete all of them.
- Name
sections- Type
- array
- Description
The complete set of sections, with the same semantics.
Request
curl -X PUT https://api.babele.co/api/ProjectForm/4501 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJleGFtcGxlIiwiZXhwIjoxNzQzODY1MjA3fQ.DEMO_SIGNATURE_NOT_A_REAL_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Accelerator intake — project questions","communityId":999,"questions":[{"id":8001,"title":"Traction","question":"What traction do you have so far?","questionOrder":0,"answerType":8,"mandatoryAnswer":true,"editableAnswer":true,"privacyLevel":2,"conditionalLogicType":0}]}'
Response
{
"id": 4501,
"name": "Accelerator intake — project questions",
"communityId": 999,
"lastEditionDate": "2026-08-07T10:31:52.407611Z",
"isDefaultCommunityProjectForm": false,
"sections": [],
"questions": [
{
"id": 8001,
"title": "Traction",
"question": "What traction do you have so far?",
"questionOrder": 0,
"answerType": 8,
"isProjectField": false,
"mandatoryAnswer": true,
"editableAnswer": true,
"privacyLevel": 2,
"questionOptions": [],
"defaultProjectFormQuestionId": null,
"sectionId": null
}
]
}
Delete a project form
This endpoint allows you to delete a project form. It responds with 204 No Content.
A form can only be deleted while none of its questions have been answered. Once any project has answered any question on it, the form is kept.
Path parameters
- Name
id- Type
- integer
- Description
Required. The ID of the form to delete.
Possible errors
- Name
404 Not Found- Description
No form matches
id.
- Name
500 Internal Server Error- Description
At least one question on the form already has answers, so it cannot be deleted.
Request
curl -X DELETE https://api.babele.co/api/ProjectForm/4501 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJleGFtcGxlIiwiZXhwIjoxNzQzODY1MjA3fQ.DEMO_SIGNATURE_NOT_A_REAL_TOKEN"
Response
204 No Content
Remove a project form question
This endpoint allows you to remove a single question from a project form without resending the whole form. It responds with 204 No Content.
Removing a question also removes every answer projects have already given
to it, and it does so without warning you first. This cannot be undone.
If you only want to stop asking a question, consider clearing
includeInProjectProfile instead of deleting it.
A question that an application definition currently links to cannot be removed. Repoint or drop that link first — see Linking application questions to the project form below.
Path parameters
- Name
questionId- Type
- integer
- Description
Required. The ID of the question to remove.
Request
curl -X DELETE https://api.babele.co/api/ProjectForm/RemoveQuestionById/8001 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJleGFtcGxlIiwiZXhwIjoxNzQzODY1MjA3fQ.DEMO_SIGNATURE_NOT_A_REAL_TOKEN"
Response
204 No Content
Duplicate a project form
This endpoint allows you to deep-copy a project form — its questions, options, sections and conditional logic — into a new form. Answers are never copied. It responds with the new form.
The copy is never marked as the community's profile form, even when the source was. Only administrators of the source form's community may duplicate it.
Path parameters
- Name
id- Type
- integer
- Description
Required. The ID of the form to copy.
Request body attributes
- Name
name- Type
- string
- Description
The new form's name. Defaults to
Copy of {source name}.Projectsis reserved for a community's own profile form and is rejected here.
- Name
targetType- Type
- string
- Description
The kind of form to create. Send
Projector leave it out; any other value is rejected.
Possible errors
- Name
400 Bad Request- Description
targetTypeis not a supported value, or the resulting name would be the reservedProjects.
- Name
403 Forbidden- Description
You are not an administrator of the source form's community.
- Name
404 Not Found- Description
No form matches
id.
Request
curl -X POST https://api.babele.co/api/ProjectForm/4501/Duplicate \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJleGFtcGxlIiwiZXhwIjoxNzQzODY1MjA3fQ.DEMO_SIGNATURE_NOT_A_REAL_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Accelerator intake — round 2","targetType":"Project"}'
Response
{
"id": 4632,
"name": "Accelerator intake — round 2",
"communityId": 999,
"creationDate": "2026-08-07T10:44:19.552103Z",
"isDefaultCommunityProjectForm": false,
"sections": [],
"questions": [
{
"id": 8114,
"title": "Traction",
"question": "What traction do you have so far?",
"questionOrder": 0,
"answerType": 8,
"mandatoryAnswer": true,
"privacyLevel": 2,
"questionOptions": [],
"defaultProjectFormQuestionId": null,
"sectionId": null
}
]
}
Linking application questions to the project form
An application definition's question list is not a single form. It is an ordered mix of two kinds of question: the definition's own application questions, and questions taken straight from a project form. A question of the second kind is not a copy — it is the project form question itself, shown inside the application. That is what linking means here, and it is why an applicant only answers the project profile once.
The mix lives in applicationDefinitionQuestionOrders on the create and update bodies of an application definition, and comes back as questionOrders when you read one. See Applications for those endpoints in full.
applicationDefinitionQuestionOrders array items
- Name
questionType- Type
- integer
- Description
Which side the entry comes from:
1a project form question (a link),2one of the definition's own application form questions.
- Name
projectFormQuestionId- Type
- integer | null
- Description
The project form question to link. Set it when
questionTypeis1, and leaveapplicationFormQuestionIdnull.
- Name
applicationFormQuestionId- Type
- integer | null
- Description
The application form question to show. Set it when
questionTypeis2, and leaveprojectFormQuestionIdnull.
- Name
order- Type
- integer
- Description
The entry's position in the mixed list the applicant sees.
Which questions you can link to
Which project form the IDs must come from depends on projectFormId on the application definition:
- Name
projectFormId- Type
- integer | null
- Description
null— the default — links against the community's own project form, so valid IDs are thequestions[].idvalues fromGET /api/Community/{id}/ProjectForm. Set it to the ID of one of the community's other project forms to link against that one instead; valid IDs then come fromGET /api/ProjectForm/{id}. A new definition may not pointprojectFormIdat the community's own profile form — leave itnullfor that.
Reading a definition back with GET /api/ApplicationDefinition/{id} saves you a lookup: projectForm on the response is already the resolved form behind its questionType: 1 entries.
How answers travel
Answers to linked questions are submitted in projectAnswers on the application body, separately from the application's own answers, and each is keyed by the project form question it belongs to. Because they are stored against that question, they are the project's answers — nothing needs copying across when the application is accepted, and by the time the project is live in the community its profile already carries them.
Rejecting an application changes none of this.
Constraints
- Name
Removing a linked question- Description
A project form question that a definition currently links to cannot be deleted while the link exists. Drop or repoint the entry first.
- Name
Reuse- Description
There is no uniqueness rule on either side. One project form question may be linked from any number of definitions and rounds at once.
- Name
Project fields across rounds- Description
When the rounds of one application group use their own project forms, each project field answer type may appear in only one round of the group, and the project name field must be in the first round. Breaking either rule is rejected with
400 Bad Request.
Request
curl -X POST https://api.babele.co/api/ApplicationDefinition \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJleGFtcGxlIiwiZXhwIjoxNzQzODY1MjA3fQ.DEMO_SIGNATURE_NOT_A_REAL_TOKEN" \
-H "Content-Type: application/json" \
-d '{"communityId":999,"name":"Accelerator 2026","formId":88,"projectFormId":null,"createProject":true,"applicationDefinitionQuestionOrders":[{"questionType":2,"applicationFormQuestionId":7001,"projectFormQuestionId":null,"order":0},{"questionType":1,"applicationFormQuestionId":null,"projectFormQuestionId":781,"order":1},{"questionType":1,"applicationFormQuestionId":null,"projectFormQuestionId":782,"order":2}]}'
Read back
{
"id": 305,
"name": "Accelerator 2026",
"communityId": 999,
"formId": 88,
"projectFormId": null,
"usesDefaultProjectForm": true,
"questionOrders": [
{ "questionType": 2, "applicationFormQuestionId": 7001, "projectFormQuestionId": null, "order": 0 },
{ "questionType": 1, "applicationFormQuestionId": null, "projectFormQuestionId": 781, "order": 1 },
{ "questionType": 1, "applicationFormQuestionId": null, "projectFormQuestionId": 782, "order": 2 }
],
"projectForm": { "id": 1258, "name": "Projects", "isDefaultCommunityProjectForm": true }
}
Applicant answers
{
"applicationDefinitionId": 305,
"projectName": "SolarKit",
"projectAnswers": [
{ "formId": 1258, "formQuestionId": 781, "answer": "Modular solar kits for rural clinics." },
{ "formId": 1258, "formQuestionId": 782, "answer": null, "optionAnswerOrder": 1 }
]
}
Sending applicationDefinitionQuestionOrders replaces the whole mix. To
remove one link, resend the array without that entry; to repoint it, resend it
with a different projectFormQuestionId. Omitting the array leaves the
current mix untouched, and sending [] clears it.
Mirroring a round question onto the default form
When a round uses its own project form, its questions can be kept in step with the community's profile form. Set defaultProjectFormQuestionId on a question of the round's form to the ID of the question on the community's default project form it corresponds to.
What mirroring does
Every time the round's form is saved, the mirrored question takes its prompt text, its isFilterable flag, its privacyLevel and its options from the default form's question — so anything you send for those fields on a mirrored question is ignored. This is a pull: editing the default question does not reach the mirrored one until that form is next saved.
When an application is accepted, an answer given against a mirrored question is also written onto the default form's question, unless that question already has an answer for the project.
Rules
- Name
Same community- Description
The target must be a question on the same community's default project form.
- Name
Same answer type- Description
The target's
answerTypemust match the mirroring question's exactly.
- Name
Not on the default form- Description
defaultProjectFormQuestionIdcan only be set on a question that belongs to one of the community's other project forms, never on the profile form itself.
- Name
Removing the target- Description
Deleting the default form's question clears the pointer on anything mirroring it. The mirrored question keeps its last synced text and options and simply stops following.
Breaking any of the first three rules causes the save to be rejected. Send null to stop mirroring.
Request
curl -X PUT https://api.babele.co/api/ProjectForm/4501 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJleGFtcGxlIiwiZXhwIjoxNzQzODY1MjA3fQ.DEMO_SIGNATURE_NOT_A_REAL_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Accelerator intake — project questions","communityId":999,"questions":[{"id":9101,"title":"Stage","question":"What stage is your startup at?","questionOrder":0,"answerType":0,"mandatoryAnswer":true,"editableAnswer":true,"privacyLevel":1,"conditionalLogicType":0,"defaultProjectFormQuestionId":782}]}'
Response
{
"id": 4501,
"name": "Accelerator intake — project questions",
"communityId": 999,
"isDefaultCommunityProjectForm": false,
"questions": [
{
"id": 9101,
"title": "Stage",
"question": "What stage is your startup at?",
"questionOrder": 0,
"answerType": 0,
"isFilterable": true,
"privacyLevel": 1,
"questionOptions": [
{ "id": 1200, "questionOption": "Idea", "questionOptionOrder": 0 },
{ "id": 1201, "questionOption": "MVP", "questionOptionOrder": 1 },
{ "id": 1202, "questionOption": "Revenue", "questionOptionOrder": 2 }
],
"defaultProjectFormQuestionId": 782,
"sectionId": null
}
]
}
