Overview
Endpoints for working with BDScript, BDFD's scripting language. A code checker/validator that catches syntax errors before you run your code (used in `!run` in the BDFD Server), and a fuzzy function check/lookup to find the correct function name.
Authentication
Include your API key in the
Authorization
header as a Bearer token with the
BDTools-
prefix for authenticated endpoints.
// Authorization header format Authorization: Bearer BDTools-YOUR_API_KEY_HERE
Rate Limits & Restrictions
- ▸ POST /bdscript-checker is not rate limited.
- ▸ GET /function-check is public and requires no authentication.
// Base URL for all BDScript endpoints https://api.bdtools.xyz
/bdscript-checker
Validates BDFD code for syntax errors, argument issues, and BDFD requirements. Returns detailed error messages with line numbers to help you fix issues quickly. Function definitions are loaded from a local JSON file for fast validation.
Input Sources
The API accepts code via two sources in the
code field:
- Raw BDFD code: Paste your code directly.
- Pastebin URL: Provide a link to a paste (standard or raw).
Pastebin Support
-
• Supported URLs: Both standard (
https://pastebin.com/S6u3Ut7W) and raw (https://pastebin.com/raw/S6u3Ut7W) formats are accepted. - • Processing: The API automatically converts standard URLs to raw URLs to fetch the content.
- • Safety: Strict prefix checking, content size limited to 500KB, 5-second fetch timeout.
Headers
| Header | Value |
|---|---|
| Authorization |
Bearer BDTools-YOUR_API_KEY
|
Request Body
{ "code": "$setUserVar[test;1;2;3;4]" }
Success Responses
{ "errors": [ { "function": "$setUserVar", "line": 1, "message": "$setUserVar - Too many arguments, expected up to 4, got 5" } ], "hasErrors": true, "statistics": { "functions": 1, "fakeFunctions": 0, "arguments": 5, "variables": ["points"] } }
{ "errors": [], "hasErrors": false, "statistics": { "functions": 3, "fakeFunctions": 0, "arguments": 5, "variables": ["level", "points"] } }
-
functions- Total number of real (known) function calls in the code -
fakeFunctions- Total number of fake (unknown) function calls that don't exist in BDFD -
arguments- Total number of arguments across all functions -
variables- Array of unique variable names used (sorted alphabetically). Includes variable get/set functions, extracts only the first argument (variable name), deduplicates, and only includes static names.
Validation Features
The validator performs comprehensive checks to catch errors before your code runs:
1. Unknown Functions
Warns if a function doesn't exist in the BDFD function list. All unknown functions show warnings, including those nested inside other function arguments.
Note: Only
$
by itself (without a function name) is treated as a literal
string and won't trigger a warning. Everything else that starts
with
$
followed by a name is treated as a function call.
2. Argument Count Validation
Validates minimum and maximum argument counts. Handles functions with multiple signatures (different argument patterns).
Argument Counting Rules:
-
• No brackets:
$function= 0 arguments -
• Empty brackets:
$function[]= 1 empty argument -
• Semicolons separate arguments:
$function[A;B]= 2 arguments -
• Trailing semicolon counts:
$function[A;]= 2 arguments (second is empty)
3. Empty Argument Validation
Checks if empty arguments are allowed based on function definition.
4. Enum Validation
Validates that enum arguments use valid values from the allowed list.
{ "function": "$addButtonCV2", "line": 1, "message": "$addButtonCV2 - Expected valid enum value in position 3, got 'invalid'. Valid values: danger, link, primary, secondary, success" }
5. Type Validation
Validates argument types including Number, Boolean, Integer, and Snowflake (Discord IDs).
Type Rules:
-
• Number/Integer: Must
be numeric (e.g.,
123,-45,3.14) -
• Boolean: Must be
true,false,yes,no,1, or0 -
• Snowflake: Must be
17-19 digit Discord ID
-
Special case - $roleGrant:
Requires
+or-operator before role ID -
•
+123456789012345678adds the role -
•
-123456789012345678removes the role -
•
123456789012345678without operator will error -
• Works with find functions:
+$findRole[Staff]
-
Special case - $roleGrant:
Requires
-
• URL: Must be a valid
http://orhttps://URL, only validated for pureURLtype arguments, notString | URLunions.
Special Value: The BDFD
special value
!unchanged
is recognized in
$modifyChannel,
$modifyRole, and
$editThread
only and skips type validation. This value indicates "keep the
current value unchanged".
6. JSON Syntax Validation
Validates JSON syntax in
$jsonParse
to catch malformed JSON.
7. Bracket Matching
Detects unclosed brackets during function extraction.
Important:
Escaped brackets
\]
don't count as closing brackets because they're part of the text
content.
Examples:
-
•
$sendMessage[hello\]→ Error (escaped bracket, missing actual closing bracket) -
•
$sendMessage[hello\]]→ Valid (escaped bracket as content, then closing bracket) -
•
$sendMessage[hello→ Error (missing closing bracket)
7a. Invalid Bracket Wrapping
Detects accidentally doubled brackets in function arguments.
Why this happens: BDFD
uses single brackets
[]
with semicolons to separate arguments. Writing
$function[[arg]]
instead of
$function[arg]
is always invalid.
8. Unclosed Blocks
Detects unclosed control flow blocks like
$if,
$try, and
$async.
Scope-aware matching:
Blocks are matched within their nesting scope. A
$if
inside a function argument must be closed inside that same
argument — the
$endif
outside won't match it.
Examples:
-
•
$description[$if[x==y]ok]$endif- Error: $if inside $description is unclosed -
•
$description[$if[x==y]ok$endif]- Valid: $if and $endif both inside $description -
•
$if[x==y]$sendMessage[ok]$endif- Valid: both at top level
Block Pairs:
-
•
$if...$endif(note:$elseis optional) -
•
$try...$endtry(note:$catchis optional) -
•
$async...$endasync
9. Multiple $else and $catch Detection
Detects:
-
• Multiple
$elsestatements in the same$ifblock (only one allowed) -
• Multiple
$catchstatements in the same$tryblock (only one allowed) -
•
$elseifappearing after$elsein the same$ifblock
The correct order for
$if
blocks is:
$if
→
$elseif
(optional) →
$else
(optional)
{ "function": "$else", "line": 5, "message": "Multiple $else statements in the same $if block (started on line 1). Only one $else is allowed per $if block." }
{ "function": "$catch", "line": 4, "message": "Multiple $catch statements in the same $try block (started on line 1). Only one $catch is allowed per $try block." }
{ "function": "$elseif", "line": 6, "message": "$elseif cannot appear after $else in the same $if block (started on line 1). Use $elseif before $else." }
10. Context Validation (Parent-Child Relationships)
Ensures context-dependent functions have their required parent functions defined before use.
Order Checking:
Parent must be defined before child, checking both line number and position within the line. This allows multiple related functions on the same line:
-
•
$jsonParse[{}] $jsonArray[eLog] $jsonPretty[3]- Valid: Correct order -
•
$jsonArray[eLog] $jsonParse[{}]- Error: Wrong order
Modal Components:
•
$addTextInput
requires
$newModal
Select Menus:
•
$addSelectMenuOption
requires
$newSelectMenu
or
$editSelectMenu
Components v2:
-
•
$addThumbnailrequires$addSection -
•
$addMediaGalleryItemrequires$addMediaGallery -
•
$addButtonCV2requires$addActionRowor$addSection -
•
$addUserSelect,$addRoleSelect,$addMentionableSelect,$addChannelSelect,$addStringSelectrequire$addActionRow -
•
$addStringSelectOptionrequires$addStringSelect
Text Splitting:
•
$splitText,
$getTextSplitLength,
$joinSplitText, etc. require
$textSplit
JSON Functions:
•
$json,
$jsonUnset,
$jsonArray, etc. require
$jsonParse
or
$jsonSet
Note:
$addTextDisplay
and
$addSeparator
can exist without a parent (optional).
11. Components v2 Validation Rules
Validates BDFD's requirements for Components v2 to catch errors before running code.
- • Sections: Must have at least 1 Text Display and 1 accessory (thumbnail or button); Duplicate section IDs are not allowed (each section needs a unique ID)
- • Containers: Must have at least 1 child component
- • Media Galleries: Must have at least 1 media item
- • Action Rows: Cannot mix buttons and select menus
- • Limits: Maximum 5 buttons or 1 select menu per action row
- • Parent-Child Order: Parents must be defined before children reference them; Empty required parent IDs trigger errors
-
• Select Menus:
$newSelectMenuand$editSelectMenumust have at least 1 option;$addStringSelectmust have at least 1 option; Max value cannot exceed the number of options (you can't select 25 items if you only have 1 option)
12. Modal Text Input Validation
Validates
$addTextInput
arguments beyond just requiring
$newModal.
Rules:
- • Min and max length must be integers between 0 and 4000
- • Min cannot exceed max
- • Value cannot exceed 4000 characters (resolved after escape sequences)
- • Placeholder cannot exceed 100 characters
- • All checks skipped when values contain variable or number-returning functions
Example Errors:
{ "function": "$addTextInput", "line": 1, "message": "$addTextInput - Minimum length must be between 0 and 4000, got 5000" }
{ "function": "$addTextInput", "line": 1, "message": "$addTextInput - Minimum length (10) cannot be greater than Maximum length (5)" }
{ "function": "$addTextInput", "line": 1, "message": "$addTextInput - Placeholder cannot exceed 100 characters, got 150" }
13. Negative Number Validation
Validates that functions which don't accept negative numbers receive valid values.
Functions checked:
-
•
$random- Both min and max must be >= 0 -
•
$cropText- Cannot accept negative values -
•
$sqrt- Cannot accept negative values
14. Min/Max Value Validation
Validates min and max value constraints for select menus.
$newSelectMenu / $editSelectMenu:
- • Min must be >= 0
- • Max must be <= 25
- • Min must be < Max (strict inequality)
CompV2 Select Menus ($addUserSelect, $addRoleSelect, $addChannelSelect, $addMentionableSelect, $addStringSelect):
- • Min must be >= 0
- • Max must be <= 25
- • Min must be <= Max (can be equal)
15. Variable Name Validation
Validates that "Variable name" arguments contain literal string names, not function calls.
Affected functions:
-
•
$userLeaderboard[Variable name;Sort] -
•
$serverLeaderboard[Variable name;Sort] -
•
$globalUserLeaderboard[Variable name;Sort] -
•
$getLeaderboardPosition[Variable type;Variable name;Sort;ID] -
•
$getLeaderboardValue[Variable type;Variable name;Sort;Position;Return type]
Why? These functions
expect a literal variable name (like
"points"
or
"level"), not a dynamic value. Even variable functions like
$getUserVar[]
are not allowed.
16. Function Context Compatibility
Validates that functions are used in compatible contexts.
Rules:
-
•
Embed builders cannot be inside message senders:
-
- Embed builders:
$description,$title,$footer,$author,$addField,$color,$thumbnail,$image, etc. -
- Message senders:
$sendMessage,$channelSendMessage,$dm,$reply,$replyIn
-
- Embed builders:
-
•
Message senders cannot be nested inside other
functions
(except control flow like
$if,$else,$try, etc.): Message senders are actions that send messages, they don't return values
Valid examples:
-
•
$if[x==y]$sendMessage[yes]$endif- Valid: control flow is allowed -
•
$setUserVar[x;$sendMessage[hi]]- Valid: variable functions can contain anything -
•
$setUserVar[x;$description[hello]]- Valid: variable functions can contain anything
Variable Bypass System
When arguments contain variables, ID-returning functions, number-returning functions, boolean-returning functions, or the special value !unchanged, the validator automatically skips certain validations because their values are dynamic, unknown at validation time, or have special meaning.
Variable functions that trigger bypass:
$var[],
$getUserVar[],
$getServerVar[],
$getChannelVar[],
$getVar[],
$message[],
$noMentionMessage,
$mentioned[]
(user input)
ID-returning functions (skip snowflake validation):
$authorID,
$channelID,
$messageID,
$guildID,
$findChannel,
$findRole,
$findUser, and 20+ more ID functions
Number-returning functions (skip number validation):
$sum,
$random,
$membersCount,
$boostCount, and 30+ more count/math functions
Boolean-returning functions (skip boolean validation):
$isBot,
$checkCondition,
$hasRole,
$channelExists, and 20+ more check/is functions
Special values:
!unchanged
- Works in
$modifyChannel,
$modifyRole, and
$editThread
only
Escape Sequences
The validator properly handles BDFD escape sequences:
| Escape | Result | Description |
|---|---|---|
$c[]
|
$
|
Escaped dollar sign (displays $ as text) |
\;
|
;
|
Escaped semicolon (includes ; in argument) |
\]
|
]
|
Escaped closing bracket (includes ] in argument) |
\\
|
\
|
Escaped backslash (displays \ as text) |
%{DOL}%
|
$
|
Alternative dollar escape |
%{-SEMICOL-}%
|
;
|
Alternative semicolon escape |
%ESCAPED%
|
]
|
Alternative bracket escape |
Multi-line Code Support
The API automatically handles multi-line code with line breaks. Users can type their code naturally with proper formatting, and the API will parse it correctly.
Error Sorting
Errors are automatically sorted by line number for easier debugging. This helps you fix issues from top to bottom.
Error Responses
{ "error": "Invalid or missing API key." }
{ "error": "Missing or invalid 'code' field" }
{ "error": "Method not allowed. Use POST." }
{ "error": "Internal server error" }
Paste this into a BDFD command to validate user-provided code.
Capture the code with
$message
and store it in a variable to prevent BDFD from executing it.
$nomention $var[code;$message] $httpAddHeader[Authorization;Bearer BDTools-YOUR_API_KEY_HERE] $httpPost[https://api.bdtools.xyz/bdscript-checker; { "code": "$var[code]" } ] $httpResult
-
User types:
!run $sendMessage[Hello World!] -
$messagecaptures the raw code after the command -
Store it in
$var[code]to prevent execution - Send to API for validation
-
Display the result with
$httpResult
$var
before using it in JSON. If you use
$message
directly in the JSON, BDFD will execute the code instead
of sending it as text.
/function-check
Looks up a BDFD function by name using fuzzy matching. Useful for
finding the correct function name when you're unsure of the exact
spelling. Accepts the function name with or without the
$
prefix, with or without brackets.
Input Methods
In priority order:
-
• Path parameter:
/function-check/sendMessage -
• Query parameter:
?input=sendMessage -
• POST body:
{ "input": "sendMessage" }
Query Parameters
-
•
input(string, optional) — The function name to look up
Success Response
{ "input": "sendmesage", "normalizedInput": "sendmesage", "matchedFunction": "$sendMessage", "suggestedFunction": "$sendMessage[]", "exact": false, "confidence": "82%" }
-
input— The raw input you provided -
normalizedInput— Input after stripping$, brackets, and whitespace -
matchedFunction— The best matching BDFD function name -
suggestedFunction— Same but with empty brackets appended -
exact—trueif exact match,falseif fuzzy -
confidence— How confident the matcher is (100% = exact match)
Example Requests
-
•
/function-check/sendMessage— exact match -
•
/function-check/sendmesage— fuzzy match -
•
/function-check/$getUserVar— strips $ automatically -
•
/function-check/$setUserVar[name;value]— strips brackets automatically
Error Responses
{ "error": "Missing function input.", "hint": "Call /function-check/<function-name> or provide ?input=<function-name>" }
{ "error": "No matching function found.", "input": "xyzqwerty" }