The way to identify different Apple IIs is described in Apple II Miscellaneous Tech Note #7. Excerpting from that document:
To identify which computer of the Apple II family is executing your program, you must check the following identification bytes. These bytes are in the main bank of main ROM (shadowed on the Apple IIgs), and you should make sure that this bank is switched in before making decisions based on the contents of these locations.
Machine $FBB3 $FB1E $FBC0 $FBDD $FBBE $FBBF
-----------------------------------------------------------------------------
Apple ][ $38 [$60] [$2F]
Apple ][+ $EA $AD [$EA] [$EA]
Apple ][ J-Plus $C9 [$AD] [$EA] [$EA]
Apple /// (emulation) $EA $8A
Apple IIe $06 $EA [$C1]
Apple IIe (enhanced) $06 $E0 [$00]
Apple IIe Option Card $06 $E0 $02 $00
Apple IIc $06 $00 $FF
Apple IIc (3.5 ROM) $06 $00 $00
Apple IIc (Org. Mem. Exp.) $06 $00 $03
Apple IIc (Rev. Mem. Exp.) $06 $00 $04
Apple IIc Plus $06 $00 $05
Apple IIgs (see below)
The Apple IIe Card for Macintosh LC uses the same identification bytes ($FBB3 and $FBC0) as an enhanced Apple IIe. Location $FBDD allows you to tell the difference between the Apple IIe Card and an enhanced Apple IIe because $FBDD will always contain the value $02 on the Apple IIe Card. Location $FBBE is the version byte for the Apple IIe Card (just as $FBBF is the version byte for the Apple IIc family) and is $00 for the first release of the Apple IIe Card.
The ID bytes for an Apple IIgs are not listed in the table since they match those of an enhanced Apple IIe. Future 16-bit Apple II products may match different Apple II identification bytes for compatibility reasons, so to identify a machine as a IIgs or other 16-bit Apple II, you must make the following ROM call:
SEC ;Set carry bit (flag)
JSR $FE1F ;Call to the monitor
BCS OLDMACHINE ;If carry is still set, then old machine
BCC NEWMACHINE ;If carry is clear, then new machine
The IIgs ROM version information can be determined from the contents of the A/X/Y registers set by $FE1F
when the carry is clear. (The ROM versions are described in IIgs Tech Note #26.)
Bit Accumulator X Register Y Register
------------------------------------------------------------------------
Bit 15 Reserved Reserved Machine ID Number
(0 = Apple IIgs)
Bit 14 Reserved Reserved Machine ID Number
Bit 13 Reserved Reserved Machine ID Number
Bit 12 Reserved Reserved Machine ID Number
Bit 11 Reserved Reserved Machine ID Number
Bit 10 Reserved Reserved Machine ID Number
Bit 9 Reserved Reserved Machine ID Number
Bit 8 Reserved Reserved Machine ID Number
Bit 7 Reserved Reserved ROM version number
Bit 6 1 if system has memory expansion slot
Reserved ROM version number
Bit 5 1 if system has IWM port Reserved ROM version number
Bit 4 1 if system has a built-in clock Reserved ROM version number
Bit 3 1 if system has desktop bus Reserved ROM version number
Bit 2 1 if system has SCC built-in Reserved ROM version number
Bit 1 1 if system has external slots Reserved ROM version number
Bit 0 1 if system has internal ports Reserved ROM version number
Note: In emulation or eight-bit mode, only the lower eight bits are returned.
The value in A will be slightly wrong if Y is zero (i.e. ROM 0), reporting $xx1F when it should be $xx7F.
Code that does all of the checks, as well as identifying the memory configuration, can be found in Miscellaneous Tech Note #2.
One thing not covered by the tech notes is how to tell the difference between a real Apple II and one of the not-quite-clones, such as the Franklin Ace. Some versions of ProDOS had a sort of ROM checksum, and if the number came up wrong the OS would freeze during boot.