Skip to Content
Living documentation — last reviewed 2026-05-28
PlansFizikal / FreeFit — outgoing emails (Hebrew)

Fizikal / FreeFit — outgoing emails (Hebrew)

First person singular (אני) — these go out from the owner personally, not in a company voice. Context and evidence: fizikal-freefit-two-way-sync.md. Tracking: TKN-294.

Posture note. Fizikal is a direct competitor whose product Taikan replaces (ADR-0017 D2). Everything asked of them is a paying customer’s question about a documented API. Nothing asked reveals what is being built on top: no question hints at a stub seat pool, at bulk customer creation, at pushing a schedule in, or at what an aggregator sees when we write. Questions whose answer we can obtain ourselves are obtained ourselves — see §3.


1. To Fizikal (Ronen) — as sent, 2026-09-04

Merged the FreeFit commercial questions into the same mail with an explicit “forward me if you’re not the right person”, instead of a separate mail to Movement Group.

היי רונן, מה שלומך?

הצלחתי להתחבר, לקרוא את מערכת השעות ולבצע שיבוץ וביטול בהצלחה. אשמח ברשותך, אם תוכל:

1. הרשאת כתובות IP

אשמח אם תוכל לאשר גם את הכתובות הבאות:

162.220.232.251 152.55.176.240 152.55.177.193

2. בקשת הרשאה לממשקים נוספים

  1. GET classes/registration/search
  2. GET classes/schedule/guestView
  3. GET classes/search, classes/locations, classes/groups, classes/levels, employees/search
  4. POST classes/waitinglist/add, POST classes/waitinglist/remove
  5. GET pricelist/search, POST purchases/add
  6. GET entrances/search, POST customer/entry
  7. GET customer/personaldetails

3. שאלות טכניות

א. AppTypeId: עם AppTypeId=0 (או בלעדיו) מתקבלת תפוסה אמיתית. עם AppTypeId=1 מתקבלת רשימת שיעורים שונה ו-maxParticipants=0 בכל השורות, בלי שגיאה. מה המשמעות של הפרמטר, ומהם הערכים החוקיים?

ב. שיעור מלא: מהי השגיאה המדויקת כאשר השיעור מלא? את השגיאה של “לקוח כבר משובץ” זיהיתי (מוחזר success=false עם message=“ביטול”), אבל את זו של שיעור מלא טרם ראיתי, ואני חייב להבדיל ביניהן.

ג. success=false מוחזר לעיתים עם HTTP 200. האם זו התנהגות מכוונת? בנוסף, registration/remove עם מזהה שאינו קיים מחזיר 404 “Entrance Not Found”. האם זו גם התשובה עבור שיבוץ שכבר בוטל?

ד. האם יש מגבלת קריאות (rate limit) לממשק? מה הקצב המותר?

ה. X-Signature: ראיתי שהממשק מאמת גם חתימה (הודעת “Invalid X-Signature”, והפורמט הנדרש ל-X-Timestamp הוא yyyy-MM-ddTHH:mm:ss.fffZ ב-UTC). מה אלגוריתם החתימה, ומה המפתח הסודי שאיתו חותמים? והאם עבודה עם חתימה פטורה ממגבלת ה-IP?

4. שאלות לגבי פריפיט (אם אתה לא הכתובת, אשמח אם תוכל להעביר אותי למי שכן)

  1. איך המועדון מזוכה עבור כניסות פריפיט?
  2. האם זה דורש תכנית מסויימת או הגדרה מסויימת אצלכם?
  3. מה קורה כאשר מתאמן נרשם דרך פריפיט ולא מגיע?

תודה רבה ושבוע טוב, סער


2. Reserve — Movement Group / FreeFit direct

Only if Fizikal cannot or will not answer the FreeFit block above. Same three questions, expanded, plus the two that only Movement Group can answer.

Subject: אופן תיעוד ביקור וזיכוי המועדון – FreeFit / Move

היי,

אני בונה אינטגרציה שבה לוח השיעורים והשיבוצים של המועדון מנוהלים במערכת אחת ומסונכרנים למערכת הניהול שדרכה FreeFit רואה את השיעורים. לפני שאני ממשיך, חשוב לי להבין את הצד המסחרי כדי לא לפגוע בזכאות המועדון לתשלום.

  1. איך המועדון מזוכה על ביקור של מתאמן FreeFit – לפי ההרשמה לשיעור, או לפי כניסה או נוכחות שתועדה בפועל?

  2. אם הזיכוי הוא לפי כניסה – האם הכניסה חייבת להיות מתועדת דווקא במערכת הניהול המחוברת אליכם, ובאיזה אופן (סריקה בעמדה, רישום ידני, אחר)?

  3. מה קורה כאשר מתאמן נרשם דרככם ולא מגיע (no-show)? האם המועדון מזוכה, והאם נדרש דיווח מצד המועדון?

  4. מה חלון הביטול מבחינתכם, ומי מבצע ביטול של הרשמה – המתאמן באפליקציה שלכם, או שגם המועדון יכול לבטל?

  5. האם ניתן להגדיר מספר מקומות מוקצה לכל שיעור עבור מתאמני FreeFit, או שהמערכת מציגה תמיד את כלל המקומות הפנויים בשיעור?

  6. האם קיים מסלול לחיבור ישיר של מערכת ניהול נוספת אליכם, ומה התהליך והדרישות?

תודה,


3. Deliberately not asked — and who answers instead

Five questions were cut from the draft: some because the answer is already known, some because asking would disclose what is being built. Each still needs an answer; the owner of each is now us.

Not askedWhyHow it gets answered
”How do I make a customer eligible for every class?” (the date-of-birth rejection)Discloses the stub seat poolSelf-serve: give each stub a DOB around 25–30 years old at creation, then assert per class. The pool’s meta on external_entity_map records the DOB used, and the drift detector flags any class whose fromAge/toAge excludes the pool
”Can customers be created over the API? Is there a CSV import?”Discloses bulk stub creation; the spec already shows no customer-create endpointLook for a CSV import in the Fizikal CRM UI while creating the pool by hand
”Can the date-range limits be lifted, especially reading past dates?”A vendor does not loosen an API constraint for one customer — and the justification (“so I can compare and repair gaps after the fact”) describes a sync engine reconciling against their data, which is exactly what is not disclosedAccepted as permanent. FizikalReconcilerService is already forward-only by construction: a 14-day horizon in two ≤7-day windows, never a FromDate in the past. The cost is that drift older than the current week is unobservable, which raises the price of losing an outbox op — hence the transactional outbox, the (booking_id, op_type) unique index, and the cron backstop
”Does an API booking update the seat count external apps see?”This is the whole mechanism; asking states the intent outrightPartially proven: totalParticipants moved 0 → 1 → 0 on a live write, and that is the field their Move DTO (_Custom.Move.ClassMove) carries. Remains [INFERENCE] until observed on a Move-connected club — which is the better test anyway
”Does a class create/update endpoint exist or is one planned?”Discloses wanting to push a schedule inTreated as permanently absent (67 paths, none of them writes a class). The manual authoring gap and its mitigations stand
”What timezone are dates in? Can one classId repeat within a day?”Cheaper to measure than to askAnswered 2026-09-04: 264 classes over 7 days on the test club, zero duplicate classId within a day — the (classId, date) occurrence key holds. Dates come back as naive club-local (2026-09-08T00:00:00) with startTime as HH:MM:SS

Two questions from the draft were also folded rather than dropped: the seat-pool entitlement question is answered (no entitlement is required — a live write succeeded), and the customer/personaldetails request stayed in the access list without explaining what it is for.