Onboarding onto a third-party API usually starts with one example payload in a ticket. Someone pastes it into a model, mistypes a key, and the first production webhook silently drops created_at because it was never in $fillable. The JSON is the schema. Treat it that way.
Also Read: What Laravel APP_KEY actually encrypts (and when not to rotate it)
Short array syntax, then the model stub
PHP’s [] short arrays are what you want in factories and tests. var_export still emits array() in older mental models. Convert the sample once, keep it in a test as the expected shape, then generate the Eloquent stub from the same object: top-level keys as fillable, integers/floats/bools/arrays as casts, and ISO-looking strings as datetime. Nested objects stay arrays until you decide they are relations.
Also Read: Laravel: PHP date format
The JSON to PHP array converter does that conversion on this site so the stub matches the JSON you actually received, not a blog example from 2019. Rename the class, delete keys you will never persist, and add HasFactory yourself. It will not invent belongsTo relationships; that is the part that still needs a human.
Also Read: 220 billable days: turning a day rate into take-home pay
Names and versions around the model
Class names want Str::studly on the resource name, table names want Str::snake of the plural. If the payload only works on Laravel 11+ because of a cast you plan to use, check the Laravel/PHP matrix before you copy the stub into an 8.x app. The converter is a starting file, not a migration.
Keep the original JSON next to the test. When the vendor adds a field, you will see it. When they change a type from string to int, the cast list is the first thing to update.
