{
	"api_kicker": "Developer API",
	"api_title": "Build activities from your own system",
	"api_intro": "One POST per activity type. Send your content as JSON, get back an activity in your Puzzel.org account and a URL you can hand to players or drop into an iframe.",
	"api_search_placeholder": "Search endpoints, fields and settings",
	"api_search_results": "matching this page",
	"api_search_empty": "Nothing on this page matches that. Try an endpoint name, a field like activity_key, or a status code.",
	"api_search_clear": "Clear search",
	"api_nav_guide": "Getting started",
	"api_nav_endpoints": "Endpoints",
	"api_toc_label": "On this page",
	"api_hero_base_label": "Base URL",
	"api_hero_method_label": "Method",
	"api_hero_method_value": "POST, JSON body",
	"api_hero_auth_label": "Auth",
	"api_hero_auth_value": "Key + email in the body",
	"api_hero_limit_label": "Quota",
	"api_hero_limit_value": "[limit] activities a day",
	"api_hero_count_label": "Endpoints",
	"api_hero_count_value": "[count] activity types",
	"api_s_quickstart_title": "Your first request",
	"api_s_quickstart_body": "Nothing to install and no handshake: post a JSON body with your key, your email and your content. The response carries the new activity's key and the URL it plays at.",
	"api_s_quickstart_note": "Every example on this page is a complete, runnable request. Swap in your own key and content and it works as-is.",
	"api_s_auth_title": "Authentication",
	"api_s_auth_body": "There are no headers and no bearer token. Both credentials travel in the JSON body of every request, and the key is only accepted for the account that email belongs to.",
	"api_s_auth_where": "Your key sits on the account section of your dashboard, behind Show.",
	"api_s_auth_where_link": "Open my API key",
	"api_s_auth_premium": "API keys are handed out when a subscription starts, so a free account does not have one yet.",
	"api_s_auth_plans": "See the plans",
	"api_s_auth_secret": "Treat the key like a password. It creates and overwrites activities in your account, so keep it server-side and out of anything a browser can read.",
	"api_prefill_kicker": "Examples",
	"api_prefill_label": "Fill the examples with my own API key",
	"api_prefill_signed_out": "Sign in and your key drops into every example on this page.",
	"api_prefill_sign_in": "Sign in",
	"api_prefill_none": "No API key on this account yet.",
	"api_prefill_warning": "Every example now holds your real key. Don't paste one into a chat, an issue or a public repo.",
	"api_s_request_title": "The request body",
	"api_s_request_body": "Every endpoint takes the same five fields. What differs is the content field underneath them: most take an array of items, a few take one sentence or one image, and sudoku takes nothing at all.",
	"api_s_request_settings": "settings is an object of per-endpoint options. Which ones an endpoint reads is listed with it below; anything else you put there is ignored.",
	"api_col_field": "Field",
	"api_col_type": "Type",
	"api_col_notes": "What it does",
	"api_col_status": "Status",
	"api_col_meaning": "What it means",
	"api_required": "required",
	"api_optional": "optional",
	"api_default_label": "Default",
	"api_allowed_label": "One of",
	"api_in_settings": "in settings",
	"api_f_account_api_key": "Your account's API key. It goes in the body, not in a header.",
	"api_f_email": "The address your Puzzel.org account signs in with. The key is only valid together with it.",
	"api_f_title": "The name the activity gets in your dashboard. Leave it out and the endpoint uses its own fallback name.",
	"api_f_language": "Only decides the locale in the URL you get back — it does not translate anything you send. Word search also reads it to switch its filler letters to Arabic when it is \"ar\".",
	"api_f_activity_key": "Leave it out to create a new activity. Pass the key of one you already own and that activity is rebuilt instead.",
	"api_f_sentence_cryptogram": "The sentence to encrypt. Players decode it character by character.",
	"api_f_sentence_calculation": "The sentence players uncover by solving the sums.",
	"api_f_image": "Absolute URL of the picture to cut up. Sent at the top level, not inside settings.",
	"api_f_image_setting": "Absolute URL of the picture to scramble. Unlike the jigsaw's, this one lives inside settings.",
	"api_s_response_title": "What comes back",
	"api_s_response_body": "A successful call answers 200 with the new activity's key and the URL it plays at. Anything else answers with success set to false and a single error string.",
	"api_response_success": "Success",
	"api_response_error": "Failure",
	"api_s_response_urls": "The url you get back is the embed view. Swap embed for play to open it full-page, or for build to open it in the builder — the key after p= stays the same.",
	"api_s_updating_title": "Creating vs. updating",
	"api_s_updating_body": "Send activity_key and the activity behind it is rebuilt in place: its content is replaced, its name and version stamp are refreshed, and the key itself stays the same — so links and embeds you already shared keep working. Results, folder placement and every setting the endpoint does not write itself are left as they were.",
	"api_s_updating_own": "You can only update activities your own account owns. Someone else's key answers 403.",
	"api_s_updating_name": "title is applied on every update, its default included — leave it out and the activity is renamed to that endpoint's fallback name.",
	"api_s_updating_settings": "The setting blocks an endpoint writes itself are rewritten from scratch, so an update also resets those to the values you send, or to the endpoint's defaults.",
	"api_s_updating_quota": "An update costs the same as a create: one call off today's quota.",
	"api_s_limits_title": "Rate limit",
	"api_s_limits_body": "Every successful call counts, creates and updates alike. Go over and the next request answers 429 until the counter is cleared.",
	"api_s_limits_counter": "[limit] activities per account per day",
	"api_s_limits_reset": "The counter is wiped once a day by a scheduled job, not on a rolling 24-hour window.",
	"api_s_errors_title": "Errors",
	"api_s_errors_body": "Errors always arrive as JSON with the same two fields, never as an HTML page. The error string is written to be read by a person — it names the field or the limit that failed.",
	"api_err_400": "Something in the body is missing, malformed or out of range. The message names the field.",
	"api_err_401": "The email is unknown, or the key does not belong to that account.",
	"api_err_403": "The activity_key you sent belongs to a different account.",
	"api_err_429": "Today's quota is used up. It clears once a day.",
	"api_err_500": "The generator could not build a puzzle from what you sent — usually too few words, or words that cannot be fitted together.",
	"api_endpoints_title": "Endpoints",
	"api_endpoints_intro": "One path per activity type, all POST, all under the same base URL. Each one lists the content it needs, the settings it reads and a request you can run.",
	"api_group_words": "Words & letters",
	"api_group_cards": "Cards & pairs",
	"api_group_questions": "Questions & answers",
	"api_group_text": "Sentences & numbers",
	"api_group_images": "Pictures",
	"api_ep_content_label": "Content",
	"api_ep_settings_label": "Settings it reads",
	"api_ep_settings_none": "This endpoint reads no settings.",
	"api_ep_example_label": "Example request",
	"api_ep_notes_label": "Worth knowing",
	"api_ep_min_items": "At least [count] in items",
	"api_ep_no_items": "Takes no items",
	"api_ep_default_title": "Falls back to the name “[title]”",
	"api_copy": "Copy",
	"api_copied": "Copied",
	"api_toast_copied": "Copied to clipboard",
	"api_ep_open_builder": "Open the builder",
	"api_ep_back_to_top": "Back to top",
	"api_e_crossword": "Interlocks your answers into a grid and numbers the clues for you.",
	"api_c_crossword": "An array of words. Each entry pairs the answer with the clue that points at it.",
	"api_note_crossword_length": "Answers shorter than two characters are dropped before the grid is built, and at least two have to survive that.",
	"api_note_crossword_layout": "Answers are upper-cased and the generator gets twenty attempts to fit them. If it cannot place a single word the call answers 500.",
	"api_e_wordseeker": "Hides your words in a letter grid, in the directions and the shape you choose.",
	"api_c_wordseeker": "An array of words. The clue text becomes the word list players work from.",
	"api_note_wordseeker_length": "Answers under two characters are dropped, and every answer is upper-cased before it goes into the grid.",
	"api_note_wordseeker_arabic": "The grid is padded with Latin letters unless language is \"ar\", which switches the filler to Arabic.",
	"api_set_wordseeker_hidden_solution": "The leftover letters spell this out. Setting it also tells the generator to fit the solution first rather than pack in as many words as it can.",
	"api_set_wordseeker_directions": "Which ways a word may run. Leave it out and words run east, south-east and south only.",
	"api_set_wordseeker_template": "Cuts the grid into a shape instead of leaving it square.",
	"api_e_acrostic": "Stacks your answers so one column spells a hidden word.",
	"api_c_acrostic": "An array of words. Between them they have to supply every letter of the hidden word.",
	"api_set_acrostic_hidden_solution": "The word the highlighted column spells out. This endpoint will not run without it.",
	"api_note_acrostic_letters": "If the answers cannot supply the letters the solution needs, the call answers 500 rather than saving a half-built grid.",
	"api_note_acrostic_order": "The generator reorders your answers to make the column work, so the order you send is not the order players see.",
	"api_e_word-scramble": "Jumbles each answer's letters for players to sort out.",
	"api_c_word-scramble": "An array of words. The clue is shown next to the jumbled letters.",
	"api_set_scramble_hidden_solution": "An optional bonus word players enter once the rest is solved.",
	"api_note_scramble_random": "Activities made through the API always have the shuffle-the-order setting on, so the order you send is not the order players get.",
	"api_e_hangman": "Turns your words or phrases into guess-the-letter rounds.",
	"api_c_hangman": "An array of words or short phrases. The clue is the hint players see.",
	"api_e_wordle": "Makes a guess-the-word game out of every word you send.",
	"api_c_wordle": "An array of words. Players get one round per word.",
	"api_note_wordle_dictionary": "Made with the check-that-guesses-are-real-words setting on. Switch it off in the builder if your words are names or invented.",
	"api_e_typing-practice": "Turns sentences into typing drills.",
	"api_c_typing-practice": "An array of words or sentences to type out. The clue field doubles as an instruction.",
	"api_e_wheel-of-fortune": "Fills a spinning wheel with your own segments.",
	"api_c_wheel-of-fortune": "An array of segments. Each answer becomes one wedge.",
	"api_note_wheel_outcome": "Made with “show the outcome in the wheel only”, so the result is read off the wheel rather than announced beside it.",
	"api_e_memory": "Face-down cards to turn over and match in pairs.",
	"api_c_memory": "An array of pairs. Each pair holds the two cards that belong together.",
	"api_note_cards_media": "A card is an object with a type and a value. Use \"text\" for words, or \"image\", \"audio\", \"youtube\" or \"link\" with a URL in value, and add alt for a description.",
	"api_e_matching-pairs": "Two columns of cards to drag together.",
	"api_c_matching-pairs": "An array of pairs. The first card of each pair lands on one side, its partner on the other.",
	"api_e_flash-cards": "Two-sided cards to flip through.",
	"api_c_flash-cards": "An array of cards. The first card is the front, the second the back.",
	"api_note_flashcards_sides": "The endpoint stores as many cards as you send, so send exactly two per entry — front, then back.",
	"api_e_categorize": "Cards to sort into the bucket they belong in.",
	"api_c_categorize": "An array of categories, each with a name and the cards that belong in it.",
	"api_note_categorize_name": "A category sent without a name is saved as “Untitled Category”, so always send one.",
	"api_e_reorder": "A sequence players have to put back in order.",
	"api_c_reorder": "An array of sequences. Each holds its cards in the correct order.",
	"api_note_reorder_order": "The order you send is stored as the correct order — number one first.",
	"api_e_quiz": "Multiple-choice and open questions, scored as players go.",
	"api_c_quiz": "An array of questions. Multiple-choice questions carry their answers; open questions carry the answer you accept.",
	"api_note_question_types": "question_type is either \"multiple_choice\", where the right option carries isCorrect true, or \"open_answer\", which uses correct_answer instead. Left out, it is treated as multiple choice.",
	"api_note_quiz_settings": "The quiz endpoint passes settings straight through as activity setting blocks, so it is not a place for loose options — adjust the quiz in the builder afterwards.",
	"api_e_board-game": "A board to race across, with your questions on the tiles.",
	"api_c_board-game": "An array of questions, exactly the shape the quiz endpoint takes.",
	"api_set_board_tiles": "How many tiles the board has. Between 10 and 75.",
	"api_set_board_mode": "Whether players race to the finish or collect items along the way.",
	"api_e_cryptogram": "Turns a sentence into a code to crack, one character at a time.",
	"api_c_cryptogram": "One sentence, in the sentence field. This endpoint takes no items.",
	"api_note_cryptogram_no_items": "Anything you send in items is ignored — the puzzle is built from the sentence alone.",
	"api_set_cryptogram_helpers": "Which characters are given away for free as a way in: none, the most common ones, the vowels, or the ones you list yourself.",
	"api_set_cryptogram_character_list": "The alphabet the cipher is built from. Left empty, the encryption picks its own.",
	"api_set_cryptogram_extra_letters": "The characters given away when helpers is \"custom\". Ignored for the other helper modes.",
	"api_set_cryptogram_hide_unused": "Leaves characters the sentence never uses out of the key.",
	"api_e_calculation": "Hides a sentence behind sums — solve the sum, reveal the letter.",
	"api_c_calculation": "One sentence, in the sentence field. This endpoint takes no items.",
	"api_set_calc_difficulty": "The highest answer a sum is allowed to have.",
	"api_set_calc_operators": "Which operations may appear. x is multiply, : is divide.",
	"api_set_calc_max_operations": "How many operations one sum may chain together.",
	"api_set_calc_number_difficulty": "Caps the individual numbers inside a sum. Anywhere from 5 to 1000.",
	"api_note_calculation_fit": "If the constraints are too tight to encode the sentence, the call answers 400 asking you to loosen them rather than saving a partial puzzle.",
	"api_e_sudoku": "Generates a solved grid, then takes numbers back out.",
	"api_c_sudoku": "Nothing. The whole puzzle comes out of its two settings.",
	"api_note_sudoku_no_items": "Send no items and no sentence — size and difficulty are the entire input.",
	"api_note_sudoku_difficulty_sizes": "The builder only offers the difficulty for 2x3, 3x3 and 3x4. The API applies it to every size, 2x2 and 4x4 included.",
	"api_set_sudoku_size": "The size of one block, written as rows by columns — 3x3 gives the classic 9x9 grid. The endpoint only checks that it parses as two numbers, so stay with the sizes the builder offers.",
	"api_set_sudoku_difficulty": "How many numbers are left on the board to start from.",
	"api_e_jigsaw": "Cuts a picture into pieces to drag back together.",
	"api_c_jigsaw": "One image URL, in the image field. This endpoint takes no items.",
	"api_note_jigsaw_grid": "The API always makes a 4 by 4 jigsaw. Piece count, irregular pieces and flat edges are builder settings — sending rows or columns here does nothing.",
	"api_note_image_reachable": "The URL is stored as you sent it and the file is never copied, so it has to stay publicly reachable for as long as the activity is played.",
	"api_e_slidingpuzzle": "Scrambles a picture into tiles that slide into place.",
	"api_c_slidingpuzzle": "One image URL, inside settings. This endpoint takes no items.",
	"api_note_sliding_image_slot": "Unlike the jigsaw, this endpoint reads its picture from settings.image. A top-level image field is ignored and the call answers 400.",
	"api_help_title": "Something not behaving?",
	"api_help_body": "Send the request you tried and the error you got back and you'll get a real answer, from the person who wrote the endpoint.",
	"api_help_cta": "Email support",
	"api_int_kicker": "Developer integrations",
	"api_int_title": "Wire Puzzel into your own platform",
	"api_int_intro": "Puzzel can hand a player's result straight to another system — their score, how far they got, what they answered — without that system being a full LMS. This page is every channel there is: what goes out, when it goes out, and the smallest thing you have to build to catch it.",
	"api_int_hero_out_label": "Results go out via",
	"api_int_hero_out_value": "A webhook, or a message to the page around the activity",
	"api_int_hero_in_label": "Your page can",
	"api_int_hero_in_value": "Sign the player in and reset the activity",
	"api_int_hero_where_label": "Switched on",
	"api_int_hero_where_value": "Per activity, under Developer in the builder",
	"api_int_hero_plan_label": "Included with",
	"api_int_hero_plan_value": "A paid plan — these settings are off on a free account",
	"api_int_search_placeholder": "Search channels, fields and examples",
	"api_int_search_empty": "Nothing on this page matches that. Try a channel like webhook or postMessage, or a field like progress.",
	"api_int_nav_channels": "Channels",
	"api_int_s_choose_title": "Which channel do you need?",
	"api_int_s_choose_body": "Three things can leave an activity and one can come in. Which one fits depends on a single question: does the player sit inside your page, or somewhere else entirely?",
	"api_int_choose_out": "Out of Puzzel",
	"api_int_choose_in": "Into Puzzel",
	"api_int_choose_when": "Use it when",
	"api_int_choose_needs": "You need",
	"api_int_choose_setting": "Setting",
	"api_int_ch_webhook_name": "Results webhook",
	"api_int_ch_webhook_summary": "Every saved result is POSTed to a URL you own, as JSON.",
	"api_int_ch_webhook_when": "The player could be anywhere — a shared link, a QR code, someone else's site — and you want the result in your own database.",
	"api_int_ch_webhook_needs": "An HTTPS endpoint that accepts a cross-origin POST.",
	"api_int_ch_parent_name": "Results to the page around it",
	"api_int_ch_parent_summary": "The same JSON, posted to the page that embeds the activity instead of to a server.",
	"api_int_ch_parent_when": "You embed the activity in your own course page and the page itself can do something with the result.",
	"api_int_ch_parent_needs": "An iframe on your page and a message listener. No server, no CORS.",
	"api_int_ch_completion_name": "Completion signal",
	"api_int_ch_completion_summary": "One message when the player finishes, carrying nothing but that fact.",
	"api_int_ch_completion_when": "All you want to know is whether they are done — to tick the lesson off, unlock the next one, or show your own screen.",
	"api_int_ch_completion_needs": "An iframe on your page and a message listener.",
	"api_int_ch_trigger_name": "Reset from your page",
	"api_int_ch_trigger_summary": "Your page tells the embedded activity to clear the player's answers and start over.",
	"api_int_ch_trigger_when": "You have your own \"try again\" button outside the activity.",
	"api_int_ch_trigger_needs": "An iframe on your page. The message is only accepted from the page doing the embedding.",
	"api_int_s_webhook_title": "Results webhook",
	"api_int_s_webhook_body": "Switch on \"Send results to a webhook\" in the builder and give it a URL. From then on, every time the player's progress is saved, their browser POSTs the whole result to that URL as JSON.",
	"api_int_webhook_steps_title": "Setting it up",
	"api_int_webhook_step_1": "Open the activity in the builder and go to the Developer menu.",
	"api_int_webhook_step_2": "Switch on \"Send results to a webhook\" and paste your endpoint into the field below it. It has to be a full URL — a bare domain is refused — and it has to be https, because the browser blocks a plain-http call made from a page served over https.",
	"api_int_webhook_step_3": "Play the activity once yourself. The first POST lands as soon as you answer something.",
	"api_int_webhook_receiver": "A receiver, end to end",
	"api_int_webhook_timing_title": "It fires as you play, not once at the end",
	"api_int_webhook_timing_body": "A result goes out every time the entry is saved: after a pause in typing, when a card is placed, when the clock stops, and once more when the activity is finished. A long crossword is a couple of dozen calls, not one — so write your handler as an upsert keyed on playerUid and activityKey rather than as an insert. Each call carries the complete state, so the newest one always supersedes the last and a call that goes missing is made good by the next.",
	"api_int_webhook_finished_title": "Telling a finish from a save",
	"api_int_webhook_finished_body": "progress is a percentage: 100 means the activity is complete. A few types can end without reaching it — a quiz answered all the way through, a solved solution field — and those carry hasAlternateCompletion instead. Treat either as finished.",
	"api_int_webhook_cors_title": "It is sent by the player's browser",
	"api_int_webhook_cors_body": "The POST comes from the tab the activity is playing in, not from a Puzzel server. Most endpoints built to receive webhooks already accept it. If yours never sees a request, this is why: the browser asks permission first, so answer the OPTIONS preflight with an Access-Control-Allow-Origin header and the real POST follows.",
	"api_int_webhook_trust_title": "Treat the payload as a claim, not a proof",
	"api_int_webhook_trust_body": "There is no signature on the request, and it comes from a browser you do not control, so anyone who looks at the page can send you one too. That is fine for filling in a progress bar or a dashboard. For anything you would not let a student set themselves — a grade that counts, a certificate, a payment — check it against the results in your own Puzzel dashboard, or let the LMS grade connectors carry the score instead.",
	"api_int_s_parent_title": "Results to the page around it",
	"api_int_s_parent_body": "If you embed the activity, you can have that same JSON posted to your own page instead of to a server. Switch on \"Send results to the parent page\" and listen for the message. Nothing leaves the browser, so there is no endpoint to build and no CORS to think about.",
	"api_int_parent_origin_title": "Check where the message came from",
	"api_int_parent_origin_body": "Your listener hears every message posted to the page, including from other frames and browser extensions. Compare event.origin against https://puzzel.org before you trust what is in it.",
	"api_int_parent_same_title": "The same payload, the same timing",
	"api_int_parent_same_body": "This is the webhook's twin: the same fields, sent at the same moments. Everything under \"What a result contains\" applies here too.",
	"api_int_s_completion_title": "Completion signal",
	"api_int_s_completion_body": "The smallest channel, for when the result itself is none of your business: switch on \"Post a completion signal\" and your page gets one message the moment the player finishes.",
	"api_int_completion_shape": "What arrives",
	"api_int_completion_order_title": "The result is already saved when it arrives",
	"api_int_completion_order_body": "The signal is deliberately sent after the completing save has landed, so a page that reacts by reading the result back will find it there.",
	"api_int_completion_embed_title": "Only inside an iframe",
	"api_int_completion_embed_body": "Both message channels post to the page that frames the activity. Opened on its own tab there is nobody to tell, so nothing is sent.",
	"api_int_s_payload_title": "What a result contains",
	"api_int_s_payload_body": "One shape, whichever channel carries it. The player's answers are keyed by the activity's own item ids, so the same keys turn up in correctUids.",
	"api_int_col_when": "When it's there",
	"api_int_always": "always",
	"api_int_sometimes": "sometimes",
	"api_int_payload_absent_title": "Absent, not empty",
	"api_int_payload_absent_body": "A field that does not apply is left out of the JSON rather than sent as null or zero. That is how a type that does not score a run is told apart from a run that scored nothing — so read with a default and never assume a key is there.",
	"api_int_payload_example": "A finished quiz, as it arrives",
	"api_int_f_activity_key": "The activity the result belongs to. The same key you see in the activity's own URL, after ?p=.",
	"api_int_f_player_uid": "Who played, as an anonymous id. Stable for this player on this device, so it is what you key results on — it is not an email address and not a Puzzel account.",
	"api_int_f_player": "The registration fields the activity asks for, as you configured them: name, email, class, student_id and so on. Absent until the player has registered, and absent entirely on an activity that asks for nothing.",
	"api_int_f_progress": "How far through, as a percentage. 100 means finished.",
	"api_int_f_time_passed": "Time on the activity, in milliseconds.",
	"api_int_f_last_played_at": "When this result was saved, as a Unix timestamp in milliseconds.",
	"api_int_f_created": "When the attempt was started, as a Unix timestamp in milliseconds.",
	"api_int_f_player_input": "What the player actually entered, keyed by the id of the item it belongs to. The shape inside depends on the activity type — a word, a list of placed cards, a chosen option.",
	"api_int_f_correct_uids": "Which of those items are right, keyed the same way. Absent while nothing has been answered yet.",
	"api_int_f_score": "Points scored, on the types that score a run. Absent everywhere else — including on a run that genuinely scored zero, so check the key exists before you read it.",
	"api_int_f_performance": "A type's own measure of how well it went, where it keeps one — words per minute in typing practice, for instance.",
	"api_int_f_attempts": "Which run this is: 1 the first time, one more on every start over. Only on types that end a run early and count the retakes.",
	"api_int_f_knocked_out": "The run ended on a wrong answer and is over without being complete.",
	"api_int_f_alternate": "The activity was finished in a way that does not reach 100% — a quiz answered all the way through, a solution field solved. Treat it as a completion.",
	"api_int_f_missed_keys": "Characters the player kept getting wrong, most-missed first. Typing practice only.",
	"api_int_f_content_version": "Which version of the activity's content this was played against. It changes when the owner edits the questions, so an old result can be told apart from a current one.",
	"api_int_s_control_title": "Resetting the activity from your page",
	"api_int_s_control_body": "One instruction travels the other way. With \"Accept triggers from the parent page\" switched on, the page doing the embedding can clear the player's answers and put the activity back to the start — for a \"try again\" button of your own, outside the frame.",
	"api_int_control_only_title": "Reset is the only trigger",
	"api_int_control_only_body": "There is no message for submitting a result, opening the finish message, or jumping to a question. A message asking for anything other than a reset is ignored.",
	"api_int_control_guard_title": "Only the embedding page is heard",
	"api_int_control_guard_body": "The trigger is accepted from the page that frames the activity and from nowhere else — not a sibling frame, not a script on the page. The setting is off by default, so switch it on for the activities you drive.",
	"api_int_s_identity_title": "Bringing your own player identity",
	"api_int_s_identity_body": "If your platform already knows who is playing, the activity does not have to ask them again. Two handshakes exist, both for an activity inside your page, and both switched on by us rather than in the builder — they change who a result belongs to, so they are set up with you rather than from a checkbox.",
	"api_int_identity_pm_title": "Post us the player",
	"api_int_identity_pm_body": "The activity announces itself with 'app-loaded' and waits. Your page posts the player's details back, and the result is filed under them without the player typing anything or seeing a registration screen.",
	"api_int_identity_sso_title": "Post us a token",
	"api_int_identity_sso_body": "The same handshake, but your page posts the JWT your identity provider issued instead of the fields themselves. We verify it against the issuers set up for your account before the player is let in, so the identity is proven rather than claimed — this is the one to ask for when the result has to be trustworthy.",
	"api_int_identity_cta_title": "Ask us to switch it on",
	"api_int_identity_cta_body": "Tell us which of the two you want and where the activities will be embedded, and we will set your account up and walk through it with you.",
	"api_int_identity_cta_button": "Email us about identity",
	"api_int_s_create_title": "Creating activities from your system",
	"api_int_s_create_body": "Everything above is about a result coming out. Going the other way — making the activities themselves from content you already have — is the Puzzle API: one POST per activity type, and you get back a key and a URL to embed.",
	"api_int_create_link": "Read the API reference",
	"api_int_s_lms_title": "When a ready-made connector is the better answer",
	"api_int_s_lms_body": "If the platform on the other side is a real LMS, you probably do not need any of this. Grades can go back to its gradebook on their own, with nothing for you to host.",
	"api_int_lms_lti_title": "Moodle, Canvas, Brightspace, Schoology, itslearning",
	"api_int_lms_lti_body": "Launched from inside the LMS, with the score written back to its gradebook.",
	"api_int_lms_gc_title": "Google Classroom",
	"api_int_lms_gc_body": "Post an activity as an assignment and have the marks come back automatically.",
	"api_int_lms_not_title": "Not one of those?",
	"api_int_lms_not_body": "Course platforms, membership sites, intranets and anything you built yourself are exactly what the channels on this page are for. An embed plus the completion signal covers most of it.",
	"api_int_s_limits_title": "What there isn't",
	"api_int_s_limits_body": "So you don't go looking for it:",
	"api_int_limit_no_read": "No endpoint for reading results back. The API creates activities; results leave through the channels on this page, or through the exports in your dashboard.",
	"api_int_limit_no_signature": "No signature on the webhook. There is nothing to verify the request against, which is why a result should not be the only thing standing behind something that matters.",
	"api_int_limit_per_activity": "No account-wide webhook. The URL is a setting on an activity, so an activity you copy carries it along and a new one starts without it.",
	"api_int_limit_no_multiplayer": "Nothing in a team game or a live room. Both message channels and the webhook are for solo play, and the settings turn themselves off when team play is on.",
	"api_int_limit_no_retry": "No delivery queue. Nothing is stored and resent — the next save is the retry, and the run's last call is the one that matters.",
	"api_nav_integrations": "Getting results back out"
}
