Acceptable Carrier Frequency Offset for Specific BPSK system
Bottom line: Either implement a (simple) carrier recovery algorithm or use DBPSK instead of BPSK if you are ok with the 3 dB SNR penalty in performance.

If you want to do synchronous detection of BPSK, you will need to completely remove the carrier offset. If you do not correct for carrier offset, then your BPSK symbols will continue to rotate, eventually inverting; unless you know the rate of inversion you will not be able to distinguish if the data transmitted was a 1 or a 0. Knowing the rate of inversion is essentially carrier recovery/tracking.

See the figure below specific to your case showing the transmitted data in blue at your 1 KHz data rate, and the resulting real portion of your received signal with a 60 Hz carrier offset. 



Even if you reduced this carrier offset to significantly small values, you will still reach a point in time where the data that was completely real moves to the imaginary axis and then becomes real again but will be inverted. In the simplest case to answer your question, if your frequency offset was sufficiently smaller than the length of your data packet (768 bits), then it is feasible that you could determine the inversion from a preamble (but you could still have an inversion in the middle of your data depending on your relative phase, but let's assume you do a simple phase correction in your preamble as well; now if you do both phase and frequency correction in your preamble- then you are doing carrier recovery). So in this case the maximum offset would be: 

$$f_{offset} &lt; \frac{1000}{2\times768} = 0.65 \text{ Hz} $$

Which is the frequency above which the frequency offset would have rotated your data more than 180 degrees over the duration of the packet.

You can certainly implement additional coding in your message payload and therefore allow for even greater offsets-- however DBPSK would be a much easier solution on this front, but coding is feasible if you knew you could guarantee clock accuracy and wanted better SNR performance at the expense of some overhead). However be aware that with a separate transmitter and receiver clock that even if you were to manually adjust them so that you knew the clock offsets were below these limits, those clocks will drift over time and temperature where you will not be able to guarantee with your rates that the clocks will remain synchronized open loop. For example, the reasonable drift rate between two separate 10 MHz crystal oscillators is 100 Hz/day. With wide temperature changes this can be significantly worst.  That said, you could periodically measure your frequency error and from knowledge of the worst case frequency drift for your design, this measure (and correction) rate could be minimized for maximum efficiency. This is still a carrier recovery implementation with some suggestions detailed below on that front, but is to suggest that the carrier recovery operation could feasibly be once per packet, or even significantly less when you are resource constrained.

DBPSK

DBPSK (Differential BPSK) is an non-coherent BPSK modulation, meaning we do not require the transmitter and receiver to be synchronized. The block diagram showing the DBPSK demodulation process is shown in the figure below. T is the delay of one symbol, so we compare the phase of one symbol to the previous symbol to determine if a data transition occurred (a multiplier followed by a low pass filter is a phase detector with the response $V_{out} = Acos(\theta)$, so if two adjacent symbols are in phase (at any phase angle!) the output will be +A, and if they are 180° out of phase, the output will be -A. If you were not concerned with establishing the data boundaries (meaning something else downstream is doing this for you), then you could use a simple low pass filter (a moving average over a symbol duration T is a great choice due to its simplicity and the fact that it will have frequency nulls at 1/T), otherwise you will need to also establish the locations of the symbol boundaries (timing recovery) and then an integrate and dump would be the optimum solution for data decision. 



Differential encoding https://en.wikipedia.org/wiki/Differential_coding is often used in conjunction with DBPSK since the demodulation is only telling us if a symbol changed or not, but will have arbitrary inversion depending on which symbol was processed first. The demodulator is in fact providing the decoding function of differential encoding.  So in such a system, as long as the relative clocks of the transmitter and receiver are not drifting to cause more than a 180° over the time duration of 2 symbols, there will be no frequency offset related issue with demodulation. This means in your example, that over 2 ms the frequency of the transmitter or receiver (and they can be completely different frequencies) cannot change to create an additional phase offset of 180 degrees or more, which leads to a change in frequency of $\frac{1}{0.004} = 250 \text{ Hz}$. So as long as both your clocks are stable such that they do not change more than 250 Hz in 4 ms you will have no issue with this approach (suggesting that you could even use free-running undisciplined local oscillators for an ultimate low cost approach).  The primary drawback of this approach is you are using your own signal as the local oscillator, so any noise in your signal gets added to itself in the process (doubling the amount of noise for any noise that is uncorrelated from symbol to symbol). That is why DBPSK has a 3 dB SNR penalty.

Carrier Recovery

See this post for common implementations of carrier recovery for BPSK: Phase synchronization in BPSK and I draw your attention to this phase detector implementation specifically that is shown in the figure below:



If in your implementation you have the complex I and Q samples for your received data, then this could lead to a very simple carrier detection and removal technique since it only requires two real multiplications. Further, you could minimize how often you need to make this measurement based on your time drift and SNR constraints (if not resource limited, computing on every sample and averaging via the recovery loop would be optimum).

Otherwise other common techniques such as squaring your signal (which will give you a unmodulated tone that is exactly twice your carrier), and then dividing that by two to create a local synchronized carrier can be done which is also described in the referenced post.