First about your original question:
@peter.ludemann already answered but it seems that he calculated milliseconds and added them to the timestamp. The docs of date_time_stamp/2 suggest instead:
Values for month, day, hour, minute or second need not be normalized. This flexibility allows for easy computation of the time at any given number of these units from a given timestamp.
There is also an example of adding 200 days without doing 200 * 24 * 60... and so on. To add three months to the now:
?- get_time(T0), % now
stamp_date_time(T0, DT0, 'UTC'),
date_time_value(date, DT0, date(Y0,M0,D0)), % year/month/day of now
M3 is M0 + 3, % add three months!
date_time_stamp(date(Y0,M3,D0), T1),
stamp_date_time(T1, X, 'UTC'). % check result
T0 = 1714457392.7585614,
DT0 = date(2024, 4, 30, 6, 9, 52.758561372, 0, 'UTC', -),
Y0 = 2024,
M0 = 4,
D0 = 30,
M3 = 7,
T1 = 1722286800.0,
X = date(2024, 7, 29, 21, 0, 0.0, 0, 'UTC', -).
How exactly it does it and how the results compare to what you’d expect is a question too big 
Finally, for your api key expiration date, it sounds strange that you’d have to know the binary representation of a 64bit double for it. Can you share what it asks for?